How to avoid overlap of markers - openstreetmap

I've a lot markers inside of a cloudemade map. Sometimes there is a number ob markers at the same location. I use the cluster functionallity but how can I avoid that there are more then one marker on the same coordinats? In such a case, I simply want to have the marker beside each other.
var myMarkerLatLng = new CM.LatLng(<?php echo($rowg['lat'].','.$rowg['lon']); ?>);
var myMarker = new CM.Marker(myMarkerLatLng, {
title: "<?php echo($row['name']); ?>",
icon: icon
});

Our old Web Maps API is deprecated. Please use Leaflet instead of it. You can find good code examples here http://leafletjs.com/examples/quick-start.html. Is is free and easy customisable.

Related

How to allow visitors to add new markers in Openlayers or Leaflet

I'm working on an open mapping project and am trying to create a map that would enable website visitors to add markers to the map with some info input fields (markers would be visible by all after approved).
I discovered OpenLayers and Leaflet which both seem promising, and spent some time putting together basic maps, but after a lot of searching I've been unable to find anything on allowing visitors to add new markers to maps made with these two tools. Anyone know if this is possible ~~ or if there's another open source tool that would work better for this application? I'm solid in HTML//CSS and know basics of JQUERY - but am not well versed in javascript so if there are more plug-n-play tools thats preferred, but if not I'm willing to do the work to learn...
Thanks!
Yes you can, check out https://openlayers.org/en/latest/examples/draw-features.html to draw the feature(Point/Line/Polygon) on map vector layer
and then you can grab that feature and save it in database and reproduce it later depending upon your business logic.
You can save the drawing from the above example some what like this in javascript:
var features = source.getSource().getFeatures();
To get Point's coordinates :
var lonlat = features[0].getGeometry().getCoordinates();
var longitude = lonlat[0];
var latitude = lonlat[1];
But as ghybs said, you need to do back end work as well.
you need in LEAFLET but this solution is in NUXTjs add this to you code:
#dblclick to you event method and get new lat al lng points to store in database o do something:
<div id="map-wrap" style="height: 100vh">
<no-ssr>
<l-map :zoom="13" :center="[-16.5002, -68.1493]" #dblclick="newMarkerbyClient">
<l-tile-layer
url="https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png"
></l-tile-layer>
<l-marker :lat-lng="[xPosition, yPosition]"></l-marker>
</l-map>
</no-ssr>
</div>
and you script
data() {
return {
xPosition: -16.5002,
yPosition: -68.1493,
}
},
methods: {
newMarkerbyClient(e) {
console.log("x: " + e.latlng.lat + " y:" + e.latlng.lng);
this.xPosition = e.latlng.lat;
this.yPosition = e.latlng.lng;
//xPosition and yPosition are you new point provided by client and you can do anything with this
}
}
Regards from BOLIVIA

Markercluster in Mapbox

I am following markercluster examples from Mapbox library, but can't solve my problem. If you guys take a look at my working example here, you will notice this line of code:
L.mapbox.featureLayer(markerLayer).on('ready', function(e) {
What I initally thought was I could put markers inside of markercluster featureLayer, but I guess it was a wrong approach. Any solutions? Thanks.
Example following here
The mapbox example you refer to makes an AJAX call to retrieve the GeoJSON data, hence it needs to attach an on "ready" listener.
In your case your GeoJSON data is defined in your scripts, so the "ready" event will not be triggered (besides, you should use L.mapbox.featureLayer with your GeoJSON object directly, not a Feature Layer).
You can simply use the eachLayer method to iterate through all created markers within the Feature Layer, and add them into your Marker Cluster Group.
var clusterGroup = new L.MarkerClusterGroup();
var markerLayer = L.mapbox.featureLayer(markers).eachLayer(function(layer) {
clusterGroup.addLayer(layer);
});
map.addLayer(clusterGroup);
Updated Plunker: http://plnkr.co/edit/fN6xYcn1Lg532eLe39IS?p=preview

Adding several geoJSON layers in Mapbox

I have two geoJSON files, one is for drawing the lines(states.js), and another one is for adding markers on the map (marker.js).
However, when I add a line of code that is supposed to be adding the marker layer, nothing works.
var markerLayer = L.mapbox.featureLayer(markers).addTo(map);
How should I approach this? I thought featureLayer would work to add multiple layers, but it doesn't seem to be working well. Help is much appreciated.
Working example so far: Plunker
Example I'm following is here.
Couple of things wrong here. You forgot to declare your global L.mapbox.accessToken:
L.mapbox.accessToken = 'pk.eyJ1Ijoia2thZ2lsbCIsImEiOiJjaWdsdmJjeWkwMjMwdWFrcjI4eGZ3MGd2In0.WslWCpxaXxUOgUZP_VT1cg';
You're adding the statesData twice, once in a L.mapbox.featureLayer and once in a L.GeoJSON:
var statesLayer = L.mapbox.featureLayer(statesData).addTo(map);
statesLayer = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
Once is more than enough: here's a example on Plunker: http://plnkr.co/edit/kV8h69VJt2jtpqwdCpJo?p=preview

How to drag features in Open Layers 3?

In the OL3 examples I can drag objects and drop on the map, but I want to move/resize/rotate things that are already on the map like ol.geom.Point and other ol.geom objects. What is the OL3 way do do this?
Example in OL2:
OpenLayers.Control.DragFeature(layer)
Not sure why the example on OL3 website is so complicated. Dragging vector objects can be easily achieved using new ol.interaction.Modify.
Here is a simpler working example: jsFiddle
In short, if you marker was:
var pointFeature = new ol.Feature(new ol.geom.Point([0, 0]));
You can define modify interaction as :
var dragInteraction = new ol.interaction.Modify({
features: new ol.Collection([pointFeature]),
style: null
});
map.addInteraction(dragInteraction);
You can then get a event for getting the new location of marker after drag like so:
pointFeature.on('change',function(){
console.log('Feature Moved To:' + this.getGeometry().getCoordinates());
},pointFeature);
Take a look at the modify interaction (example). Though rotation is not yet supported.
I have create a simple lib that add drag interaction to openlayers 4 by slightly changing this official example: https://openlayers.org/en/latest/examples/custom-interactions.htm
you can find the lib here :
https://gist.github.com/kingofnull/0ad644be69d8dd43c05721022ca5c3a5
and you should simply add it this way:
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([new ol.interaction.Drag(),])
});
Update
I test the translate and it works in openlayer 4 and there is no need for a custom interaction. keep it in mind if you going to combine it with modify interaction you should add it before modify. here is my final code:
var map = new ol.Map({...});
var featureDrager = new ol.interaction.Translate();
var modify = new ol.interaction.Modify({...});
map.addInteraction(featureDrager);
map.addInteraction(modify);

Multiple markers on the exact same position on a Leaflet map

We use leafletJS to show maps with round about 100 markers. Some of these markers are located on exact the same position. Marker2 is above Marker1 so Marker1 isn't visible. Is there a way to rotate Markers in a way that you can see there are more then one marker?
may be you should look at https://github.com/Leaflet/Leaflet.markercluster plugin
here demo - http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.388.html
The drawback with walla's answer is that Leaflet.markercluster requires clustering, which may not be an option depending on your requirements i.e. you need to always display individual markers.
OverlappingMarkerSpiderfier-Leaflet (a bit of a mouthful) works well in this case and it's fairly well documented. It displays a 'spider' of markers on click only if they overlap i.e. if the zoom level increases so markers don't overlap, then it won't 'spider' on click, which is quite nice. Demo.
It's available as a NPM package but it isn't a proper ES module, so usage is a bit trickier than usual if you're expecting an ES module:
// Need to specifically import the distributed JS file
import 'overlapping-marker-spiderfier-leaflet/dist/oms';
// Note access to constructor via window object
// map refers to your leaflet map object
const oms = new window.OverlappingMarkerSpiderfier(map);
oms.addListener('click', (marker) => {
// Your callback when marker is clicked
});
// Markers need to be added to OMS to spider overlapping markers
markers.forEach((marker) => {
oms.addMarker(marker);
});
// Conversely use oms.removeMarker(marker) if a marker is removed
Alternatively there is a forked version (confusingly) called OverlappingMarkerSpiderfier that is a proper ES module so you can do:
import OverlappingMarkerSpiderfier from 'overlapping-marker-spiderfier'
const oms = new OverlappingMarkerSpiderfier(map);
However as of 24 Jan 2020 there's a fair bit of divergence based on commits between the two so YMMV.
FWIW I'm using the original.
If anyone is looking working sample for Angular below are the steps,
Install it via npm: npm i --save overlapping-marker-spiderfier-leaflet
Then import it into the component where you need it: import 'overlapping-marker-spiderfier-leaflet/dist/oms';
Add this line on top of the file where you import it: const OverlappingMarkerSpiderfier = (<any>window).OverlappingMarkerSpiderfier;
Add the oms markup like that: this.oms = new OverlappingMarkerSpiderfier(this.map, { nearbyDistance: 20, keepSpiderfied: true });
Add the markers to oms at the same place where you add your markers to the map so oms can track them properly this.oms.addMarker(marker);
xlm is already gave a complete answer. Thanks to him for that answer. But this is a slightly changed answer that worked for me in angular.
we had the same problem, follows the jsFiddle with the solution we found http://jsfiddle.net/atma_tecnologia/mgkuq0gf/2/
var marker1 = new google.maps.Marker({
position: myLatLng,
map: map,
icon: {
url: image,
size: new google.maps.Size(134,130), //different sizes
},
zIndex: 2, //different overlays
title: '1ยบ marker',
});