I'd like to ask if anyone knows a good solution to my problem.
I have a Rails project with a Bing map, where I need to load about 20000 pushpins.
The problem that I have is the speed of my data load. I've tried to optimize the load time by only including required fields for records (id, latitude, longitude). It made some difference but still was not a good load time.
Next thing that I've done - started loading records in batches (a couple hundred at a time). As a result, pushpins started showing up almost instantly, but again, it took a really long time to fully load the data set.
I'd really appreciate any suggestions about a better way to load the data.
Thanks in advance!
You have several solutions to achieve what you want to do but the main question would be, do you really need to display the 20k pushpins onto the map control and display them all at once? I'm pretty sure it will lack of readibility and adding to performance cost, you might consider dynamicaly restrict the number of elements that will be displayed and load only those who can really be seen.
1: Client-side clustering
Using your own implementation or the Bing Maps Module available here: http://bingmapsv7modules.codeplex.com/wikipage?title=Client%20Side%20Clustering, you can create cluster to ease the data manipulation and rendering of the pushpins.
2: Dynamicaly load (Server-side clipping and clustering)
Each time you fire 'onviewchanged', you can make an AJAX call to refresh the information and clear the previously added pin. Also, if you are a zoom level or in a specific area where you have to display every pushpin, you can create cluster of pushpins so you will display only one pushpin that says 'there are 12 pins in here'. I'm sure you get the point.
3: Composing dynamic tile on server-side or on client-side
If you need to display everything, the latest solution would be to draw things on dynamical tiles on server-side or on client-side depending on your use case, see: http://www.web-maps.com/gisblog/?p=1605
Related
Background
I'm writing a browser extension which paints over the map of komoot.com/plan.
Currently I do this by placing a canvas on top of the existing canvas.
This works well but it is static and does not yet react to when the user moves the map around or zooms into it or the website focusses a particular location on the map.
Question
How do I best tie into this event loop of map updates?
Approaches considered
I could mimic / reimplement how komoot processes user input, but this sounds fragile and unreliable and messy. I would do this by adding listeners for mouse button events and cursor movement, etc.
The page's URL contains the lat and long coordinates together with the zoom level, e.g., https://www.komoot.com/plan/#49.9535480,5.3956956,11.345z. It changes after the map has changed. I assume there's a way to be notified of changes in the URL. If so I could then dynamically update my canvas.
This would still require some level of imitation of the page's internals. However, considerably less so than option 1.
Doing so I could only update my canvas after the animation is finished. Not a deal breaker but ideally I'd want to update it frame by frame together with the map itself for a more pleasing user experience.
Additional Details
Komoot seems to be using mapbox-gl
It's a Manifest 2 Content Script extension
This is my first browser extension ever
I'm writing this in Scala.js using this excellent template
Don't let this keep you from posting javascript solutions or pointing me to javascript documentation!
Screenshot
You don't seem to have mentioned the obvious way: use the move event:
map.on('move',e => {...
// get center with map.getCenter()
});
But it's not really clear exactly what you're trying to do, so hard to advise more specifically.
I'm using Leaflet library in my ReactJS app and I wonder if there is a simple way to recognize if object clicked by user is a building.
Idea that came up to my mind is to check map colour under clicked position.
Does it make sense?
I appreciate your help.
Colleagues in comments advised to give some use-case:
App I'm working on is meant to mark antique buildings with elevation in bad shape so city architecture management had simpler job of searching for them.
Every user of this App can mark such building. To prevent hooligans from corrupting data with senseless points on map I wanted to validate as a first step if clicked point is a building.
I hope it will clarify problem a little bit.
I wonder if there is a simple way to recognize if object clicked by user is a building.
No.
You basically want to run arbitrary point-in-polygon queries against OSM's building dataset, and I will presume that you don't want to host that dataset yourself.
The simplest way to do this is to perform queries to an Overpass API server, passing a is_in query and filtering by the building tag key. The OSM website's query feature functionality uses such a technique.
With this technique you won't have to worry about hosting the data, just about creating the right Overpass API query. Please bear in mind that the Overpass API servers are run by volunteers and their resources are limited.
The second simplest way would be to download a OSM extract of you area of interest, and run the point-in-polygon queries yourself, by whatever means you like (PostGIS' ST_Intersect, turf.js, etc etc).
If you will be using Leaflet, another approach would be to use vector tiles, and set it up in such a way that the buildings thematic layer is interactive. This will require you to be aware of the limitations of the vector tile servers.
Idea that came up to my mind is to check map colour under clicked position.
That is unreliable. Think about labels on top of buildings, or the colour of the edge of the building area, or buildings that don't render with the standard colour (e.g. places of worship, monuments).
I have a request form a client and am looking for advice on the best procedure. I believe that HTML 5 can help however I'm not too experience in the more advanced features of HTML 5 to come to a conclusion.
Basically my client is looking to have a universe which in effect really is just a large graph. Plotted within the universe are elements that are added by users. This amount will increase over time. Hence the graph will increase in dimensions. The idea is to see the universe as a whole with small dots representing elements. Then a user can zoom in and/or pan the universe to discover different elements. Clicking an element bring up a dialog and more information can be gained. Zooming can happen in real time or is it acceptable to click a region and it gets bigger.
My assumption is that the best way to go about this is to use HTML 5 and Javascript. However as stated I'm new to HTML 5 and its limitations.
It would be nice if it could be light-weight and accessible on multiple devices (mobile, tables, etc).
Is HTML the solution here? What would be the best practice? Any suggestions?
A while back I built something very similar by integrating with Google Maps. I pulled addresses from my database, converted using a Geocode tool, then with PHP/Javascript combination I input the data into Google Maps (just using a simple foreach loop) and stuck the code on my site. In all, it was pretty simple since Google handles most the application.
The hardest part, IMO, was validating the addresses and converting them to Geocode.
If you want to take this route, here are some helpful links:
GOOGLE MAPS INTEGRATION DOCUMENTATION (pretty much contains everything you'll need to know)
https://developers.google.com/maps/documentation/javascript/
GEOCODING WITH GOOGLE (Limits you to 2500 hits per day)
https://developers.google.com/maps/documentation/geocoding/
And the rest I'd search here in stackoverflow.
Hopefully this helps point you in the right direction.
I try to draw a very large dataset on google map (2500+ rectangles). The rendering of the rectangles take more than 5 secs. The whole page just stuck for the 5 secs, so I am thinking about adding a loading indicator or progress bar during the rendering.
To do this, I need to trap events of rending (start,finish rendering).
I checked the google maps Api documentation, did not find anything useful. Just what to know whether there is some work around or something I miss in the api doc that can help me to trap rendering events.
As of Google Maps v3.14 the answer is no. There's no such event to listen for in the API. If you dug through the code long enough you might be able to find a hack, but given that you're in control of the rectangles you're drawing and you have a count of them, why not iterate the progress bar as you add them? Individually they will render very quickly so whether you iterate the progress before or after each is added to the map should make no difference to the user, despite the fact that it feels like the wrong order to the developer.
This gives an overview of all the events in GMapsV3 http://gmaps-samples-v3.googlecode.com/svn/trunk/map_events/map_events.html
Check if the events you need are there.
I'm seeing in another forum if the best way to do this is with Javascript or Ajax but I'm wondering if there is an even easier simpler way. I'm trying to create a web service where users can check which countries they have visited from a list of 175 or so and a World map image would then instantly update with a filled color.
There are other similar services, but I'm envisioning mine to be both updating from checks in checkboxes and by clicking on the target country in the displayed image say with an imagemap. Additionally other solutions display all the visited countries in the same color. I would like different colors for different countries or at least for those countries that touch. Eventually I would like to include a feature that enables the choice of which colors to assign countries.
I found a Sourceforge project called pwmfccd. It's simply an open source image of the world and the coordinates on the PNG image for all the countries. You can use mogrify from ImageMagick and floodfill to fill the countries with color. I have done this successfully, locally with batch files.
My ISP has told me where mogrify is located, basically "/usr/bin/mogrify". I now have a horrendously complicated cgi script which if it worked is set to redraw the world map image with each checkbox. It's here. It also redraws the whole web page with each check. The web page starts here. Of course this is not at all efficient, and I think probably the real way to go is Ajax or Javascript, so that maybe just the image gets changed and redrawn, not the whole web page. Sorry I don't even know the difference between Javascript and Ajax and their relative merits at this point.
I suppose you could make just one part of the image update with each check or click on the image instead of even just the image redrawing, but I have never even heard of a hint at being able to do that for irregularly shaped image elements like countries. So I guess an Image map and sister checkbox entries tied to mogrify events redrawing the user's personal copy of the image with an image refresh would be the only way to go.
So how do you do this with something other than Javascript or Ajax or is that definitely the way to go and if so, how would you do it? Or can you after all cut up a web based image into irregular puzzle shaped piece which you can redraw individually at will.
Thanks in advance for reading and considering answering this post.
Well, it looks like maybe my hosting company only supports using PHP with ImageMagick. At least I know better what to try create. I'm completely new to PHP, but I guess that is alright