Adding several geoJSON layers in Mapbox - 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

Related

How to loop through geojson layers on leaflet map?

I have already added geojson features to my leaflet map. I want to be able to loop through those geojson features. WHen I do map.eachLayer(function(layer) {...}) it only shows be the tile layer and none of the geojson that are added.
Rather than map.eachLayer, you should be using the .eachLayer method on the L.geoJson itself. For example:
var geoJsonLayer = L.geoJson(myGeoJson).addTo(map);
geoJsonLayer.eachLayer(function(layer) {
layer.bindPopup(layer.feature.properties.name);
});
You can also specify a function to be applied to each feature at the time you create the L.geoJson, using the onEachFeature option.

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

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',
});

Bing Maps Multiple Pushin Infoboxes

I have a map where I have multiple pushpins, and would like the infobox to support HTML content. I'm using the native infobox class, and while I have used a custom infobox, as many have suggested, I'd like to figure this one out.
The code is at: http://brickenandassociates.com/bm.php
Its not compressed or encoded, so you can just view the source.
at line 84, the options for the Infobox are set. In the description, I've tried setting a var , but am missing the syntax somewhere. Something like this :
var ibDescription = document.getElementById('ibDescription');
ibDescription.innerHTML = e.target.description;
Any guidance would be most appreciated !
Looks like you've figured this out already:
pinInfobox.setOptions({title: e.target.Title, description: e.target.Description, visible:true, offset: new Microsoft.Maps.Point(0,25)});
pinInfobox.setLocation(e.target.getLocation());
One thing I noted was that you are only using one InfoBox. I use one info box per pushpin, so I set the infobox detail at the time it is created and then only have to hide or show it.