I want to show 2 Mapbox maps side to side on the same page.
The SF map works as advertised (popup on hover), but the NY map does not show its markers. What am I doing wrong?
Thanks much!
Here is the page with a NY and a SF map: link.
In that page header I injected:
<script src='https://api.mapbox.com/mapbox-gl-js/v0.20.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v0.20.0/mapbox-gl.css' rel='stylesheet' />
The NY map code block:
<style>
.mapboxgl-popup {
max-width: 400px;
letter-spacing: 1px;
font: 16px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
}
.marker-title {
font-weight: 300;
}
</style>
<div id='mapny' style='width: 100%; height: 400px;'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94Y29vcmRpbmF0ZXMiLCJhIjoiY2lwOGhicDN3MDE5dXQ2bHk5Mmw0MGQ3YiJ9.ilUY49cMzmQGR6VKfz95CA';
var markers = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"description": "<div class=\"marker-title\">Skylight at Moynihan Station</div>",
"marker-symbol": "marker"
},
"geometry": {
"type": "Point",
"coordinates": [-73.99557 , 40.75176]
}
}, {
"type": "Feature",
"properties": {
"description": "<div class=\"marker-title\">Skylight One Hanson</div>",
"marker-symbol": "marker"
},
"geometry": {
"type": "Point",
"coordinates": [-73.97791 , 40.68511]
}
}, {
"type": "Feature",
"properties": {
"description": "<div class=\"marker-title\">Skylight Clarkson SQ</div>",
"marker-symbol": "marker"
},
"geometry": {
"type": "Point",
"coordinates": [-74.00956, 40.72825]
}
}, {
"type": "Feature",
"properties": {
"description": "<div class=\"marker-title\">Skylight Modern</div>",
"marker-symbol": "marker"
},
"geometry": {
"type": "Point",
"coordinates": [-74.00401 , 40.7511 ]
}
}]
};
var map = new mapboxgl.Map({
container: 'mapny',
style: 'mapbox://styles/mapboxcoordinates/cipfsc92i000bbkmbypwkvi1c',
center: [-73.993235, 40.712980],
pitch: 60,
zoom: 11.5
});
map.on('load', function () {
// Add marker data as a new GeoJSON source.
map.addSource("markers", {
"type": "geojson",
"data": markers
});
// Add a layer showing the markers.
map.addLayer({
"id": "markers",
"type": "symbol",
"source": "markers",
"layout": {
"icon-image": "{marker-symbol}-15",
"icon-allow-overlap": true
}
});
});
// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
map.on('mousemove', function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ['markers'] });
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';
if (!features.length) {
popup.remove();
return;
}
var feature = features[0];
// Populate the popup and set its coordinates
// based on the feature found.
popup.setLngLat(feature.geometry.coordinates)
.setHTML(feature.properties.description)
.addTo(map);
});
</script>
The SF map code block:
<style>
.mapboxgl-popup {
max-width: 400px;
letter-spacing: 1px;
font: 16px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
}
.marker-title {
font-weight: 300;
}
</style>
<div id='mapsf' style='width: 100%; height: 400px;'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94Y29vcmRpbmF0ZXMiLCJhIjoiY2lwOGhicDN3MDE5dXQ2bHk5Mmw0MGQ3YiJ9.ilUY49cMzmQGR6VKfz95CA';
var markers = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"description": "<div class=\"marker-title\">Skylight at Pier 38</div>",
"marker-symbol": "marker"
},
"geometry": {
"type": "Point",
"coordinates": [ -122.38769, 37.78257]
}
}, {
"type": "Feature",
"properties": {
"description": "<div class=\"marker-title\">Skylight at the Mint</div>",
"marker-symbol": "marker"
},
"geometry": {
"type": "Point",
"coordinates": [ -122.40725, 37.78272]
}
}]
};
var map = new mapboxgl.Map({
container: 'mapsf',
style: 'mapbox://styles/mapboxcoordinates/cipfsc92i000bbkmbypwkvi1c',
center: [-122.409898, 37.775668],
pitch: 60,
zoom: 12
});
map.on('load', function () {
// Add marker data as a new GeoJSON source.
map.addSource("markers", {
"type": "geojson",
"data": markers
});
// Add a layer showing the markers.
map.addLayer({
"id": "markers",
"type": "symbol",
"source": "markers",
"layout": {
"icon-image": "{marker-symbol}-15",
"icon-allow-overlap": true
}
});
});
// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
map.on('mousemove', function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ['markers'] });
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';
if (!features.length) {
popup.remove();
return;
}
var feature = features[0];
// Populate the popup and set its coordinates
// based on the feature found.
popup.setLngLat(feature.geometry.coordinates)
.setHTML(feature.properties.description)
.addTo(map);
});
</script>
Related
I am using Mapbox draw and i like to know is there a way to add images on each points(coordinates) of polygon ?
this is my code for the polygon:
var draw = new MapboxDraw({
displayControlsDefault: false,
controls: {
line_string: true,
polygon:true,
trash: true,
},
userProperties: true,
change the style of points and line.
styles: [
{
"id": "gl-draw-polygon-stroke-active",
"type": "line",
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-color": "#D20C0C",
"line-dasharray": [0.2, 2],
"line-width": 2
}
},
{
"id": "gl-draw-polygon-and-line-vertex-active",
"type": "circle",
"filter": ["all", ["==", "meta", "vertex"], ["==", "$type", "Point"], ["!=", "mode", "static"]],
"paint": {
"circle-radius": 10,
"circle-color": "#3c33ff",
}
}
]
});
map.addControl(draw)
Update i found a way here's my code:
first i load and add a image with the var img then i create a click function to take the coordinates from the map with lnglat and now i can put a image everywhere i clicked.
var img = 'photo';
map.on('load', function() {
map.loadImage('https://image.shutterstock.com/image- photo/colorful-flower-on-dark-tropical-260nw-721703848.jpg', function(error, image) {
if (error) throw error;
map.addImage('photo', image); // donner un nom à image
map.on('click', function (e) {
var imageId = e.lngLat.lng + e.lngLat.lat + "";
map.addLayer({
"id": imageId,
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [e.lngLat.lng, e.lngLat.lat]
}
}]
}
},
"layout": {
"icon-image": img,
"icon-size": 0.1
}
});
});
});
});
};
I have a mapbox showing a layer from a dataset of mine. But in my map also some other points of interest are shown, for example a bar, a gas station, etc that I would like not to be there. How can I hide those unwanted POI ?
I am using mapbox js with ionic3.
This is my relevant initialization code:
var questo = this;
questo.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/cjaudgl840gn32rnrepcb9b9g',
center: [11.381054062288769, 43.517016927850099],
zoom: 17.15,
pitch: 15,
});
questo.map.on('load', function () {
questo.map.addLayer({
"id": "points",
"type": "symbol",
"source": {
"type": "geojson",
"data": questo.places
},
"ssource": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-77.03238901390978, 38.913188059745586]
},
"properties": {
"title": "Mapbox DC",
"icon": "monument"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.414, 37.776]
},
"properties": {
"title": "Mapbox SF",
"icon": "harbor"
}
}]
}
},
"layout": {
"icon-image": "{icon}-15",
"text-field": "{title}",
"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
"text-offset": [0, 0.6],
"text-anchor": "top",
"icon-size": 1.20,
},
});
In the above code, questo.places contains my own personal POI (the only ones i would like to appear in the map)
Thanks very much in advance
If those POI are not coming from your dataset, they are probably from your map style.
Take a look at that map from the Mapbox Studio. On the left sidebar there should be several label layers. Try to hide/delete those that you don't need.
I have this map and displaying pointers based on users long and lat. now i have a problem with OverlappingMarkerSpiderfier. when there are more than 1 users with same long and lat. for example: 5 people live in the same building. i need OverlappingMarkerSpiderfier to show the count and then on click to sipderfy it. by default, OverlappingMarkerSpiderfier doesnt work that way.
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(52, 8),
zoom: 4
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
var oms = new OverlappingMarkerSpiderfier(map,{markersWontMove: true, markersWontHide: true, keepSpiderfied: true});
markerClusterer.setMap(map);
here is the jsfiddle http://jsfiddle.net/gL3L7zso/62/
as you can see, when i click the battefield 3. its showing 1 pointer behind it hiding 3. i need it to be the same but, display the count of pointers hiding behind.
appreciate any solution for this.
update: to make the question more clear.
updated fiddle: http://jsfiddle.net/gL3L7zso/68
One option would be to put a label on each marker in the "cluster", and put the highest labeled marker on top.
oms.addMarker(marker);
var markersNear = oms.markersNearMarker(marker, false);
marker.setLabel("" + (markersNear.length + 1));
marker.setOptions({
zIndex: markersNear.length
});
proof of concept fiddle
code snippet:
var geoJson = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"name": "Bielefeld"
},
"geometry": {
"type": "Point",
"coordinates": [8.528849, 52.030656]
}
}, {
"type": "Feature",
"properties": {
"name": "Bielefeld2"
},
"geometry": {
"type": "Point",
"coordinates": [8.528849, 52.030656]
}
}, {
"type": "Feature",
"properties": {
"name": "Bielefeld3"
},
"geometry": {
"type": "Point",
"coordinates": [8.528849, 52.030656]
}
}, {
"type": "Feature",
"properties": {
"name": "Herford"
},
"geometry": {
"type": "Point",
"coordinates": [8.676780, 52.118003]
}
}, {
"type": "Feature",
"properties": {
"name": "Guetersloh"
},
"geometry": {
"type": "Point",
"coordinates": [8.383353, 51.902917]
}
}, {
"type": "Feature",
"properties": {
"name": "Guetersloh2"
},
"geometry": {
"type": "Point",
"coordinates": [8.38, 51.9]
}
}]
};
var map = null;
var bounds = new google.maps.LatLngBounds();
var boxText = document.createElement("div");
boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";
var infobox = new InfoBox({
content: boxText,
disableAutoPan: false,
maxWidth: 0,
pixelOffset: new google.maps.Size(-140, 0),
zIndex: null,
boxStyle: {
background: "url('tipbox.gif') no-repeat",
opacity: 0.75,
width: "280px"
},
closeBoxMargin: "10px 2px 2px 2px",
closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
infoBoxClearance: new google.maps.Size(1, 1),
isHidden: false,
pane: "floatPane",
enableEventPropagation: false
});
var markerClusterer = new MarkerClusterer(map, [], {imagePath: "https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m"});
minClusterZoom = 14;
markerClusterer.setMaxZoom(minClusterZoom);
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(52.030656,8.528849),
zoom: 14
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
google.maps.event.addListenerOnce(map, 'idle', function() {
var oms = new OverlappingMarkerSpiderfier(map, {
markersWontMove: true,
markersWontHide: true,
keepSpiderfied: true
});
oms.addListener('unspiderfy', function(spidered, unspidered) {
for (var i = 0; i < spidered.length; i++) {
spidered[i].setLabel("" + (i + 1));
spidered[i].setOptions({
zIndex: i
});
}
});
markerClusterer.setMap(map);
google.maps.event.addListener(map.data, 'addfeature', function(e) {
if (e.feature.getGeometry().getType() === 'Point') {
var marker = new google.maps.Marker({
position: e.feature.getGeometry().get(),
title: e.feature.getProperty('name'),
map: map
});
google.maps.event.addListener(marker, 'click', function(marker, e) {
return function() {
var myHTML = e.feature.getProperty('name');
boxText.innerHTML = "<div style='text-align: center;'><b>" + myHTML + "</b></div>";
infobox.setPosition(e.feature.getGeometry().get());
infobox.setOptions({
pixelOffset: new google.maps.Size(0, 0)
});
infobox.open(map);
};
}(marker, e));
markerClusterer.addMarker(marker);
oms.addMarker(marker);
google.maps.event.addListener(map, 'idle', function() {
var markersNear = oms.markersNearMarker(marker, false);
marker.setLabel("" + (markersNear.length + 1));
marker.setOptions({
zIndex: markersNear.length
});
});
}
});
layer = map.data.addGeoJson(geoJson);
map.data.setMap(null);
google.maps.event.addListener(map, "click", function() {
infobox.close();
});
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map {
width: 100%;
height: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<script src="https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js"></script>
<script src="https://jawj.github.io/OverlappingMarkerSpiderfier/bin/oms.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/google-maps-utility-library-v3-infobox#1.1.14/dist/infobox.min.js"></script>
<div id="map"></div>
update
Anyone that sees this and says hey wait he used map.data.addGeoJson() and not .loadGeoJson() it's because the fiddle needs addGeoJson when loading the JSON locally. loadGeoJSson() works the same as the above code if running on a web server.
Original Question below
I'm running all this on a web server so according to the googleMaps docs loading geoJSON from the same domain is accepted as long as the URI is correct (also for dev i'm running the geoJSON request via http, not sure if that matters). To simply things i placed my JSON object in the same directory as my index.html and mapInit.js file.
According to the API docs all the functions i've tried are available in the actual reference section of Version 3.21 so i'm assuming they still work. I also have an API key which i've plugged in accordingly.
My question
Why is the loadGeoJson not functioning, am I declaring it incorrectly, or am I styling incorrectly?
Whats working
The map loads just fine and centers on the correct location, it then loads the custom marker and centers the map accordingly.
Whats not Working
When loading the geoJSON file using customLayer.loadGeoJSON("some.json") i get no errors if I switch to using customLayer.addGeoJSON("some.json") i get an invalid feature or feature collection error in the console.
Additionally customLayer.setStyle({icon:image}) doesn't seem to be setting the style I have also tried customLayer.StyleOptions({icon:image}).
So i stuck with loadGeoJson() because it seemed to be loading the JSON.
index.html
!DOCTYPE html
<html>
<body>
<div id="myMap" style='padding:0; height: 800px; width:100%;'></div>
</body>
<center>
<script src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<script> src="mapInit.js"</script>
</html>
mapInit.js
function init(){
var mapCanvas = document.getElementById('myMap');
var map;
var image = "../images/marker.svg";
var userCenter = new google.maps.LatLng(30.382288, -97.727447);
var mapOptions = {
draggable: true,
zoomControl: true,
scrollwheel: true,
disableDoubleClickZoom: false,
zoom: 8,
center:userCenter
};
map = new google.maps.Map(mapCanvas,mapOptions);
var customLayer = new google.maps.Data();
customLayer.loadGeoJson("some.json");
customLayer.setStyle({ title: '#',
icon:image,
map: map,
});
customLayer.forEach(function(feature) {
var point = new google.maps.LatLng(feature.getProperty('coordinates'))
var mark = new google.maps.Marker({
position: point,
title: '#',
icon:image,
map: map,
draggable: false,
animation: google.maps.Animation.DROP
});
});
// customLayer.setMap(map);
var marker = new google.maps.Marker({
position: userCenter,
title: 'Your Location',
icon:image,
map: map,
draggable: true,
animation: google.maps.Animation.DROP
});
}
I have also tried adding customLayer.setMap(map); instead of declaring map:map in the setStyle() with no luck.
The some.json file is below and in the correct directory as Chrome and firefox consoles are registering 200 OK
some.json
{
"type": "FeatureCollection",
"features":[
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [30.388256,-97.739863]},
"properties": {"prop0": "value0"}
},
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [30.389904,-97.739226]},
"properties": {"prop1": "value1"}
},
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [30.384617,-97.739348]},
"properties": {"prop2": "value2"}
},
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [30.387876,-97.7396]},
"properties": {"prop3": "value3"}
}
]
}
Your coordinates are backwards in your GeoJSON. GeoJSON is [Longitude, Latitude], 90+ degrees is an invalid latitude. If you paste your GeoJSON into geojsonlint.com, you will see all your markers at the south pole.
The GeoJSON should be:
{
"type": "FeatureCollection",
"features":[
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [-97.739863,30.388256]},
"properties": {"prop0": "value0"}
},
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [-97.739226,30.389904]},
"properties": {"prop1": "value1"}
},
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [-97.739348,30.384617]},
"properties": {"prop2": "value2"}
},
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [-97.7396,30.387876]},
"properties": {"prop3": "value3"}
}
]
};
proof of concept fiddle
code snippet:
function init() {
var mapCanvas = document.getElementById('myMap');
var map;
var image = "http://maps.google.com/mapfiles/ms/micons/blue.png";
var userCenter = new google.maps.LatLng(30.382288, -97.727447);
var mapOptions = {
draggable: true,
zoomControl: true,
scrollwheel: true,
disableDoubleClickZoom: false,
zoom: 13,
center: userCenter
};
map = new google.maps.Map(mapCanvas, mapOptions);
var customLayer = new google.maps.Data();
map.data.addGeoJson(jsonData);
map.data.setStyle({
title: '#',
icon: image,
map: map,
});
map.data.forEach(function(feature) {
var point = new google.maps.LatLng(feature.getProperty('coordinates'))
var mark = new google.maps.Marker({
position: point,
title: '#',
icon: image,
map: map,
draggable: false,
animation: google.maps.Animation.DROP
});
});
// customLayer.setMap(map);
var marker = new google.maps.Marker({
position: userCenter,
title: 'Your Location',
icon: image,
map: map,
draggable: true,
animation: google.maps.Animation.DROP
});
}
google.maps.event.addDomListener(window, 'load', init);
var jsonData = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-97.739863, 30.388256]
},
"properties": {
"prop0": "value0"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-97.739226, 30.389904]
},
"properties": {
"prop1": "value1"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-97.739348, 30.384617]
},
"properties": {
"prop2": "value2"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-97.7396, 30.387876]
},
"properties": {
"prop3": "value3"
}
}]
};
html,
body,
#myMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="myMap" style='padding:0;'></div>
How do you put GeoJSON attribute information in a popup with OpenLayers 3
I need to display the informations included in my geojson file into the popup. Here is my method but it gives me undefined.
My GeoJson file:
{ "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "name": "Caen - Campus 3 "}, "geometry": { "type": "Point", "coordinates": [-0.353538,49.148791] } }, { "type": "Feature", "properties": { "name": "Caen "}, "geometry": { "type": "Point", "coordinates": [-0.369770,49.184403] } }
Here is my method
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element
});
map.addOverlay(popup)
map.on('click', function(evt){
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if ( feature ) {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
var nom = feature.getProperties();
//var nam = nom.type;
popup.setPosition(coord);
$(element).popover({
'placement': 'top',
'html': true,
'content': '<p>'+feature.get('name')+'</p>'
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
I create the popup when I click on it displays me 'undefined'. I think that don't use the good method to put the 'name' object included on the GeoJson file: feature.get('name')
I think that I don't uses the best method. Thank for your help.