How to display Leaflet markers near the 180° meridian? - javascript

I am using Leaflet 1.0.0-rc.2+e02b5c9. I know the default is rendering all markers, polylines ... from longitude -180 to 180 as screen shot here:
However, I want to show the map as this longitude I want to show at this point (It is middle sea between Japan and US):
but you see all the markers are not rendered on the right side. Even though, If i set
worldCopyJump: true
when I drag to the right, all markers are appeared on the right but they are disappeared on the left and vice versa. Actually, I want they are appeared at the same time.
Any ideas to fix that??

Just make sure that the longitudes of your markers are in the range 0..360 instead of in the range -180..180. See a working example.
i.e. instead of
L.marker([0,170]).addTo(map);
L.marker([0,-180]).addTo(map);
L.marker([0,-170]).addTo(map);
Do something like
L.marker([0,170]).addTo(map);
L.marker([0,180]).addTo(map);
L.marker([0,190]).addTo(map);
In other words, if a longitude is smaller than zero, add 360 to it. You might want to use L.Util.wrapNum(lng, [0,360], true) instead, if you plan to filter all your longitudes at once.

A similar issue has been encountered and reported on the Leaflet Github
The solution is to increase the longitude of your markers if their initial longitude is below 0.
var totalMarkers = markerPositions.length;
for(var i = 0; i<totalMarkers; i++){
var mData = markerPositions[i];
if (mData.lon < 0) {
mData.lon += 360;
}
L.marker([mData.lat, mData.lon]).addTo(map);
}

Another approach is to leverage the Leaflet.RepeatedMarkers plugin, which will display a copy of each marker per 360 degrees of longitude:
Applying this to markers near the antimeridian works as well, e.g.:
var myRepeatingMarkers = L.gridLayer.repeatedMarkers().addTo(map);
L.polyline([[-85,180],[85,180]]).addTo(map);
L.polyline([[-85,-180],[85,-180]]).addTo(map);
myRepeatingMarkers.addMarker(L.marker([0,140]));
myRepeatingMarkers.addMarker(L.marker([0,150]));
myRepeatingMarkers.addMarker(L.marker([0,160]));
myRepeatingMarkers.addMarker(L.marker([0,170]));
myRepeatingMarkers.addMarker(L.marker([0,180]));
myRepeatingMarkers.addMarker(L.marker([0,-170]));
myRepeatingMarkers.addMarker(L.marker([0,-160]));
myRepeatingMarkers.addMarker(L.marker([0,-150]));
myRepeatingMarkers.addMarker(L.marker([0,-140]));
will display something like:
Check out the live example for using Leaflet.repeatedMarkers with markers near the antimeridian.

Thank you all for the help. Actually, I am not using your suggested codes but I got me the idea to fix it.
This is my solution, hope it helpful for others looking for same solution:
Screenshot that was solved
Always display the icon and its copy on the map (on longitude range you want, in my case, it is from 0 to 360)
makeMarkers: (item) ->
markers = []
markers.push(item.makeMarker())
copy_marker = item.makeMarker()
copy_marker.setLatLng( new L.LatLng(copy_marker._latlng.lat, copy_marker._latlng.lng + 360) )
markers.push(copy_marker)
markers
In Item class:
makeMarker: ->
LeafletIcon = L.Icon.extend(
options: {
iconSize: [25, 25],
iconAnchor: [10, 10],
popupAnchor: [0, 0]
},
)
icon = new LeafletIcon( {iconUrl: this.iconUrl} )
marker = L.marker([this.latitude, this.longitude], {icon: icon, zIndexOffset: 10})
marker.id = this.id
marker
Thank you again.

Related

Leaflet Multipolyline

i want to use the addLatLng function to add a new point to my multipolyline. I am able to use the function with a normal single polyline, but with for example two lines, i don't know how i can access the second ring to add the new point.
I have tried some of those...
var polyline = L.polyline([[], []], {color: generateRandomColor()}).addTo(map);
var point = {lat: lat, lng: long};
var arr = polyline.getLatLngs();
polyline[1].addLatLng(point); //nope
polyline.addLatLng(arr[1], point); //nope
polyline.addLatLng(point) //yes but adds to the first polyline
I also can't understand the hint from the docs -
addLatLng( latlng, <LatLng[]> latlngs?)
Adds a given point to the polyline. By default, adds to the first ring of the polyline in case of a multi-polyline, but can be overridden by passing a specific ring as a LatLng array (that you can earlier access with getLatLngs).
Can you please give me an example in javascript code?
Thank you so much!
You add the ring in the wrong order. Use following:
polyline.addLatLng(point, arr[1]); //yep

riseOnHover property is not working in leaflet js

I'm creating a map using leaflet js, which has several markers.
The question is, how can I get riseOnHover property to work?
As mentioned in docs:
If true, the marker will get on top of others when you hover the mouse
over it.
So I got a simple code like:
let map = L.map('map').setView([0, 0], 2);
let tile = L.tileLayer('map/{z}/{x}/{y}.png', {
minZoom: 2,
maxZoom: 5,
noWrap: true,
});
tile.addTo(map);
let options = {
riseOnHover: true,
};
let marker = L.marker([0, 0], options);
marker.addTo(map);
But nothing happens. I also tried it with serveral markers at once, in case maybe there should be more than one marker to get riseOnHover to work, but that didn't work either.
I found the solution. Unfortunately, the docs explain riseOnHover property in a way which the reader thinks it is used to rise markers a little in y axis, but in real use, it increases the z-index of the marker which we are hovering.
It will work well if you have several markers which are overlapping each other. Just hover on one of them and you see the magic!

Compare position of markers in the same array

I've got an array of Google Maps Markers that I get after clicking on cluster.
I would need to check if the markers of this array have the same position. Because I can find myself in the situation where it could be, where in one cluster all of markers have the same position.
There is my code :
google.maps.event.addListener(markerCluster, 'clusterclick', function(cluster) {
var markers = cluster.getMarkers();
map.setCenter(markers[0].getPosition());
map.setZoom(map.getZoom()+10);
for(i in markers) {
// Here, how to compare each marker (by comparing the position) between them of markers ?
markers[i].setMap(cluster.getMap());
marker = markers[i];
}
cluster.clusterIcon_.hide();
setTimeout(function(){
google.maps.event.trigger(marker, 'click');
},100);
});
So my question, is how to compare each marker (by comparing the position) between them of markers array ? How to check if they have the same position ?
Thanks.
EDIT :
I found the solution :
const bounds = cluster.getBounds();
const areMarkersCoincident = bounds.getNorthEast().equals(bounds.getSouthWest());
Thanks for your help !
It depends on what you are trying to achieve.
For example, if you just need a simple clustering solution you can just use google maps marker clusters: https://developers.google.com/maps/documentation/javascript/marker-clustering
But for something else you can just compare positions of the markers.
For that, you have latitude and longitude.
Here you can read the documentation of LatLng class in google maps and see that it has method equals which can compare two coordinates. https://developers.google.com/maps/documentation/javascript/reference/coordinates#LatLng
But don't forget that in some cases you might need to compare not just marker positions, but also if the marker icons intersect. For that, you can either use LatLngBounds https://developers.google.com/maps/documentation/javascript/reference/coordinates#LatLngBounds and it has a method contains

how to make the map clusters larger distance in less dense area in map instead of showing markers

I am using google map(clustering version) from the following link:
google map clusterer
everything is good and for example when I have 1000 location it clusters them but when I have 200 location and density is not high it does not clusters. I want to clusters even those that are not dense what should I do? is there anyway that I can change level of sensitivity of this google map to distance and zoom to be able to cluster even markers in a less dense area?
As you figured out which parameters to use with the above comments, here is how to pass these params to your marker cluster constructor:
var mcOptions = {
gridSize: 50,
minimumClusterSize: 10
};
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
Where map is your map object and markers is your markers array. The numbers used are only for example. You have to play with these to get the desired results. Hope this helps.
Swift
cluster size change worked for me this way in the latest version and its super easy
// Set up the cluster manager with the supplied icon generator and
// renderer.
let iconGenerator = GMUDefaultClusterIconGenerator()
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let renderer = GMUDefaultClusterRenderer(mapView: mapView,
clusterIconGenerator: iconGenerator)
renderer.delegate = self
renderer.minimumClusterSize = 5 // Here is the setting
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm,
renderer: renderer)
clusterManager.setDelegate(self, mapDelegate: self)

OpenLayers is showing 720 degree around the globe

My current OpenLayers looks like the following:
a wrong map http://i1179.photobucket.com/albums/x384/yoyomyo/Picture2.png
It has twice as many continents as there should be.
I was trying to set Bounds to my map, but the entire map just refuses to render:
var map = new OpenLayers.Map('map', {restrictedExtent: new OpenLayers.Bounds(-180, -90, 180, 90)});
var layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
map.addLayers([layer]);
map.setCenter(
new OpenLayers.LonLat(-71.147, -42.472).transform( new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject()),
12);
Does any Map guru know what I did wrong?
WrapDateLine
Try wrapDateLine:false
It sounds like you want to set maxExtent.
http://trac.osgeo.org/openlayers/wiki/SettingZoomLevels
Otherwise I have no clue. :)
It would be easier to answer with an example to work off of. I would zoom in 12 is pretty far out. And yes you can zoom in on OSM http://www.openstreetmap.org/
In that site, they use these values
var centre = new OpenLayers.LonLat(-0.1, 51.5);
var zoom = 5;
setMapCenter(centre, zoom); //It calls map.setCenter()
Okay I give up. I think this is just the way OpenStreetMap displays its map.
I have seen many demos and they are all like the one above.

Categories

Resources