Leaflet marker clustering - javascript

I am following closely the example of https://switch2osm.org/using-tiles/getting-started-with-leaflet while adding more useful functions. Everything works out of the box except the additional clustering of marker using the plugin from https://github.com/Leaflet/Leaflet.markercluster. I thought to replace the line
var plotmark = new L.Marker(plotll);
with
var plotmark = new L.MarkerClusterGroup(plotll);
while this triggers an error in leaflet.js. Any idea?

Did you read this ?
You should have
var group = new L.MarkerClusterGroup();
group.addLayer(new L.Marker(plot11));
... Add more layers ...
map.addLayer(group);

While the previous answer of FranceImage shows the correct syntax, the problem was caused by an incompatibility between the current markercluster and leaflet version. Switching back to Leaflet 0.7.3 (May 2014) solved it.

Related

Leaflet js map only showing a few tiles

I'm trying to create an custom stationary map using the Leaflet JavaScript library and keep running into a major issue where most of the map tiles for the coordinates do not render. I'm defining & showing the map like so
function initmap() {
map = new L.Map('map');
var osmUrl = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}.png';
var osm = new L.TileLayer(osmUrl);
map.addLayer(osm);
}
var lat = 40.120910;
var lng = -74.978602;
var startLatLng = new L.LatLng(lat, lng);
initmap();
map.setView(startLatLng, 16);
It seems like it should work, but the map div never shows the full map/all tiles. I know there is coverage for this particular area because I've been using another person's service that using this library and map to look at this location. This code is structured based off of their code.
This website is using the exact coordinates, map server, and the leaflet js script and is able to render all tiles fine.
Here's a JSFiddle to show the code (and issue) in action. Any idea why this is happening or how to fix it?
Missing Leaflet CSS: https://npmcdn.com/leaflet#1.0.0-rc.1/dist/leaflet.css
Updated JSFiddle: https://jsfiddle.net/t14rLknv/7/
(BTW you can upgrade to Leaflet 1.0.0-rc.3, new official CDN on unpkg.com, see http://leafletjs.com/download.html)

Move marker dynamically

I am using Openlayers.Layer and OpenLayers.Marker to display a marker on the map.
It is positioned correctly and I can successfuly show it and hide it doing:
marker.display(boolean);
But I try to change its position before displaying it but with no success. I already tried this:
var projections = {
g: new OpenLayers.Projection("EPSG:4326"),
p: new OpenLayers.Projection("EPSG:900913")
};
var newlonlat = new OpenLayers.LonLat(newlon, newlat).transform(projections.g, projections.p);
marker.lonlat = newlonlat
layer.redraw();
(no errors triggered but position does not change)
and also tried this:
var px = map.getPixelFromLonLat(newlonlat);
marker.moveTo(px);
layer.redraw();
(it throws an error inside getPixelFromLonLat function. Error: c is null)
Why can't I move markers dynamically and what is the best way to do it?
Edit:
Maybe the problem resides in my position projection transformation when using second option:
new OpenLayers.LonLat(newlon, newlat).transform(projections.g, projections.p);
Edit 2
So, going deeper I found that marker.map property was null, so after its initialization I did:
var marker = new OpenLayers.Marker(lonlat, icon);
marker.map = map;
where map is an OpenLayers.Map object and now its working fine. Don't know why but it fixed it.
marker.moveTo works fine for me:
var px = map.getPixelFromLonLat(new OpenLayers.LonLat(newLon,newLat));
marker.moveTo(px);
Hope this helps :-)
To workaround the problem I did:
marker.lonlat = new OpenLayers.LonLat(newlon, newlat);
layer.removeMarker(marker);
layer.addMarker(marker);
layer.redraw();
It seems stupid removing and adding the same marker to just update its position but it works. It may be slower when doing this to a large group of markers though.
Try:
marker.lonlat = new OpenLayers.LonLat(newlon, newlat);
layer.drawMarker(marker);
(not testet)

google Maps: $.goMap() with custom overlayMapType

First: I try to remake a Website called regionalkarten.com
It's a German publisher of Maps. This page uses the Google API v2 to show our custom maps.
My Job is to update the Page to API v3.
Now I found the jQuery GoMap Plugin and I try to use it, but it doesn't seem to support custom maps.
I tried to define a Overly with the custom Map
var ehsTypeBOptions =
{
getTileUrl: function(coord, zoom)
{
var x = coord.x;
var y = coord.y;
return "http://regionalkarten.com/_map/ehs_village_maps/is_maps/z"+zoom+"/"+coord.y+"/"+coord.x+".png";
},
tileSize: new google.maps.Size(256, 256),
};
and load it into the map with:
map.overlayMapTypes.insertAt(0, new google.maps.ImageMapType(ehsTypeBOptions));
That works fine without GoMap. So I tried:
$.goMap.overlayMapTypes.insertAt(0, new google.maps.ImageMapType(ehsTypeBOptions));
and guess what, it didn't work :(
GoMaps Webpage and Google aren't very helpful. Keep in mind that I have to load the custom map into an overlay. I need the real google maps behind the overlay because our maps are not gapless.
I hope you got some ideas or experience with GoMap.
Thank you.
$.goMap does not return the native google.maps.Map-instance, so you can't use the Maps-API-methods there.
The google.maps.Map-instance may be accessed via $.goMap.map .
Beyond that: I would suggest not to use this library, there haven't been any updates since 1 year, and this all can be done without any additional library.
More important: before you continue working with ImageMapType, this is not the right MapType for you, because it appears that the TileServer don't serve tiles for the complete world.
When the user pans or zooms so that a area is in viewport where no tile is available, this area would be shown as a gray space. You better use a Overlay MapType and set the background-image of the overlays to the TileUrl(additionally you may use a condition that checks if a Tile is available at all to reduce unnecessary request to the tile-server)

Openlayers initial extent

According to the OpenLayers documentation, the constructor, OpenLayers.Map(), allows for an additional property extent which is "The initial extent of the map" (see here).
However, I cannot get it to have any effect. I know I can set an initial extent by calling .zoomToExtent() after constructing the map. But I would like to use this extent property because I set a zoomend event in the eventListeners property but don't want it to trigger with an initial call to .zoomToExtent(). Does anyone have a clue how to use this extent property?
This is the code that isn't working
map = new OpenLayers.Map('map',{
extent: bounds,
layers: [osmLayer,vectorLayer],
projection: "EPSG:900913",
eventListeners: {
zoomend: function() {
//..zoomend event listener code
}
}
});
In the above example:
bounds is a valid OpenLayers.Bounds object
osmLayer and vectorLayer are valid OpenLayers.Layer objects of which osmLayer is the base layer.
What happens with above code is that the map is completely zoomed out (in fact you can't actually see anything) and any attempts to pan results in errors being thrown. To get to map into a correct state the user has to zoom in and then panning works again and you can see the map.
I'm afraid I'm not sure off-handedly how to make the code you listed work, however the following alternative has worked for me:
map = new OpenLayers.Map('map',{projection: new OpenLayers.Projection("EPSG:4326")});
//ADD A BUNCH OF LAYERS AND SUCH HERE
//Set map center to this location at this zoom level
map.setCenter(new OpenLayers.LonLat(-93.9196,45.7326),5);
As a last resort, you could put a line at the beginning of your zoom function:
if(!map_ready) return;
And then set the variable map_ready to true at the appropriate time.
I ran into the same problem.
The "extent" option mentioned in the documentation is there probably by mistake. It does not exist. I checked the source code and could not see any code handling such option. I contacted the author and he already created a pull request for the removal of this option from the documentation.

Google Maps ClusterManager on API V3 not working on reload / initial load

I am trying to use the Google Maps V3 API ClusterManager from http://cm.qfox.nl/ to cluster together markers on a map, but I'm hitting the same error in my code as in the original web site - an error when the page is loaded the first time, or reloaded:
Uncaught TypeError: Cannot call method 'fromLatLngToPoint' of undefined ClusterManager_v3.js:586
ClusterManager.latlngToPoint ClusterManager_v3.js:586
ClusterManager._getMarkerBounds ClusterManager_v3.js:645
ClusterManager._cacheMarkerIcon ClusterManager_v3.js:580
ClusterManager.update ClusterManager_v3.js:345
(anonymous function) ClusterManager_v3.js:91
It works fine after the initial load, so I'm fairly sure it's because of a timing issue - e.g., the map or marker isn't initialized before it being used. Unfortunately, I can't figure out a way to wait for everything to initialize because Javascript isn't my first language. Any help or pointers would be most welcome. The source from the web site is the code I'm using almost exactly.
UPDATE:
If found that changing the line:
cm._requestUpdate(50);
to
cm._requestUpdate(250);
Prevented the error. Changing it to 150 resulted in the error occurring 3/10 times. I'm not entirely sure this is a fix, but it maybe so I'm leaving this posted just in case anyone else has a better solution or wants to know mine.
For using Projection methods , it must be initialized. Map will trigger "projection_changed" event, when Projection will be created.Only after that you can use map.getProjection(). So my suggestion is, to add "projection_changed" event's listener, and initialize ClusterManager when it is called:
google.maps.event.addListenerOnce(map, 'projection_changed', function(){
var cm = window.cm = new ClusterManager(
map,
{
objClusterIcon: new google.maps.MarkerImage('markers/cluster.png', false, false, false, new google.maps.Size(20,20)),
objClusterImageSize: new google.maps.Size(20,20)
}
);
// now json contains a list of marker positions. lets add them.
for (var i = 0; i < json.length; ++i) {
.....
}
cm._requestUpdate(50);
});

Categories