Loading GeoJSON into Mapbox - javascript

When I use GeoJSON inside the HTML it works, but when I try to load externally it doesn't.
My HTML file and GeoJSON file are in the same folder in site.
I try to open picture popups with markers.
Thanks a lot!
L.mapbox.accessToken = 'lalalalala';
var southWest = L.latLng(40.875557, 29.235992),
northEast = L.latLng(41.277226, 28.749847),
bounds = L.latLngBounds(southWest, northEast);
var map = L.mapbox.map('map', 'mapbox.light', {
maxBounds: bounds,
maxZoom: 19,
minZoom: 11
});
var myLayer = L.mapbox.featureLayer()
.loadURL('http://terkedilmisarabalar.mudurlugu.org/geojson/terkedilmisarabalar.geojson')
.on('ready', function() {
myLayer.eachLayer(function(layer) {
map.fitBounds(myLayer.getBounds());
layer.bindPopup(layer.features.properties.name);
});
})
.addTo(map);
myLayer.setGeoJSON(geojson);
myLayer.on('onclick', function(e) {
e.layer.openPopup();
});
myLayer.on('onrelease', function(e) {
e.layer.closePopup();
});
Here is an example GeoJSON file:
{
type: 'FeatureCollection',
features: [
{
"type": "Feature",
"properties": {
"name": "Acıbadem Cd. No:117",
"description": "<img src=\"https://lh3.googleusercontent.com/DkEl65k9kZAtvPdf9HuE22aIAJKUKBDtiL0m5vZBRqn9nVsgcQIQYdi03gt5yhOKcrEvTQpctu_xnLVfhzzt6Tr3fGtsxuIJSqPrf7R9p-0faSL-YRxTzyn44B8KVB8\" height=\"200\" width=\"auto\" /><br><br>",
"gx_media_links": "https://lh6.googleusercontent.com/fmIjm4ynkTWSkmzcOfoMCoVgnm6h9pQ8KINgHqhjx-ZNQMrT05NqsZo2Lv5d6FwFFakmqOzl_ruRKvu34jbC96U3nKaxlu0sul6W4qXU1ily4PNbLCQTsR2BGKOxervb"
},
"geometry": {
"coordinates": [
29.045881,
41.005992,
0
],
"type": "Point"
}
}

Related

Center VueLeaflet view to all geoJson geometries from multiple layers

I have a variable list of geoJson layers (that I'm naming as sectors) on my map. I need to center the view to fit all geometries.
I'm using Vue2Leaflet (v2.5.2) and Leaflet (v1.6.0).
Each geoJson object is like this:
{
"type": "FeatureCollection",
"features":
[
{
"type": "Feature",
"properties":
{
"id": "4200051",
"name": "Abdon Batista",
"description": "Abdon Batista"
},
"geometry":
{
"type": "Polygon",
"coordinates": [[[-51.0378352721, -27.5044338231], ...]]
}
}
]
}
And it's stored directly in geoSectors: [ geoJson1, geoJson2, ... ].
Here's the code:
<template>
<div class="home">
<l-map ref="mapControl" :zoom="zoom" :center="center" :options="mapOptions">
<l-tile-layer :url="url" :attribution="attribution"/>
<l-control-zoom position="bottomright"/>
<!-- Sectors-->
<l-geo-json v-for="sector in geoSectors" :key="sector.id" :geojson="sector" :options="options"/>
</l-map>
</div>
</template>
<script>
import { latLng, latLngBounds } from "leaflet";
export default {
data() {
return {
zoom: 6,
center: latLng(-25.005973, -50.537109),
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '© OpenStreetMap contributors',
mapOptions: {
zoomSnap: 0.1,
zoomControl: false
},
geoSectors: []
}
},
mounted(){
let list = [];
//Gets the list from a file.
this.geoSectors = list;
var bounds = this.geoSectors; //HERE: Get bounds of the list.
this.$refs.mapControl.mapObject.fitBounds(bounds);
},
computed: {
options() {
return {
onEachFeature: this.onEachFeatureFunction
};
},
onEachFeatureFunction() {
return (feature, layer) => {
layer.on('click', function (e) {
//Shows sector details.
});
//Tooltips.
layer.bindTooltip("<div><p>Sector: "feature.properties.name +"</p></div>", {
permanent: false,
sticky: true
});
};
}
},
}
</script>
How can I fit the map view to display all geoJson layers, with the maximum zoom level possible?
I managed to solve it. Here's the code:
//You need to import featureGroup from leaflet:
import { latLng, featureGroup } from "leaflet";
//After building your geoJson layers, just call this:
this.$nextTick().then(() => {
var group = new featureGroup();
this.$refs.mapControl.mapObject.eachLayer(function(layer) {
if (layer.feature != undefined)
group.addLayer(layer);
});
this.$refs.mapControl.mapObject.fitBounds(group.getBounds(), { padding: [20, 20] });
});

Leaflet.js - Create layers and add markers depending on geojson category data?

I have a .js file with coordinates for internships:
var internships = [{
"features": [
{"type":"Feature","properties":{"category":"entretient","Name":"green"},"geometry":{"type":"Point","coordinates":[50.807149, 3.162994]}},
{"type":"Feature","properties":{"category":"securité","Name":"blue"},"geometry":{"type":"Point","coordinates":[50.334421, 3.290146]}},
{"type":"Feature","properties":{"category":"secretaria","Name":"red"},"geometry":{"type":"Point","coordinates":[50.744787, 2.256216]}}
]
}];
I've found this bit of code allowing me to create layers depending on a property and here what my JS looks like:
$.getScript("CoordinatesPdC.js");
function mapLoad() {
var sécuritéLayer = new L.LayerGroup();
var secrétariatLayer = new L.LayerGroup();
var entretientLayer = new L.LayerGroup();
var map = L.map('map').setView([50.2910, 2.7775], 8);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, '
}).addTo(map);
var marker = L.marker([50.2910, 2.7775]).addTo(map);
var entretientLayer = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "entretient");
}
}).addTo(map);
var sécuritéLayer = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "sécurité");
}
}).addTo(map);
var secrétariatLayer = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "secrétariat");
}
}).addTo(map);
}
window.onload = mapLoad;
But now I have to create the markes assigned to these layers, how can I achieve that?
Your markers are already assigned to each later. In your example, you create a layer (with all of its markers) and immediately add it to the map using .addTo(map); Here's the code responsible for it.
var sécurité = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "sécurité");
}
}).addTo(map);
Now, you probably want to only display a certain layer based on user input. If so, I suggest adding the related layer to the map on a click event. Then when the event is triggered a layer is added. Here's the code for doing that. sécurité.addTo(map)
A layer is removed using map.removeLayer(sécurité);
Below is a working example based on your initial code. (I did write it in jQuery as my vanilla JavaScript could be better) You can also view it on jsFiddle here.
I left some comments in the code to explain what each part does. I hope that helps you with your understanding.
var internships = [{
"features": [{
"type": "Feature",
"properties": {
"category": "entretient",
"Name": "green"
},
"geometry": {
"type": "Point",
"coordinates": [3.162994, 50.807149]
}
},
{
"type": "Feature",
"properties": {
"category": "securité",
"Name": "blue"
},
"geometry": {
"type": "Point",
"coordinates": [3.290146, 50.334421]
}
},
{
"type": "Feature",
"properties": {
"category": "secretaria",
"Name": "red"
},
"geometry": {
"type": "Point",
"coordinates": [2.256216, 50.744787]
}
}
]
}];
$(document).ready(function() {
// Create an object to keep track of active layers and each layer with its markers
const layers = {
active: [],
entretientLayer: new L.LayerGroup(),
sécuritéLayer: new L.LayerGroup(),
secrétariatLayer: new L.LayerGroup(),
};
// create the map
var map = L.map('map').setView([50.8010, 3.1675], 6,5);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, '
}).addTo(map);
// based on the category assign a marker to the layer
layers.entretientLayer = L.geoJson(internships, {
filter: function(feature, layer) {
return (feature.properties.category === "entretient");
}
})
layers.sécuritéLayer = L.geoJson(internships, {
filter: function(feature, layer) {
return (feature.properties.category === "securité");
}
})
layers.secrétariatLayer = L.geoJson(internships, {
filter: function(feature, layer) {
return (feature.properties.category === "secretaria");
}
})
// register click event
$('button').on('click', function(e) {
const layerName = e.target.name;
// if a layer is already active, remove it from the map and the active array
if (layers.active.includes(layerName)) {
layers.active = layers.active.filter(layer => layer !== layerName);
map.removeLayer(layers[layerName]);
} else {
// add the layer to the map and to the active array
layers.active.push(layerName);
layers[layerName].addTo(map);
}
});
});
#map {
height: 140px;
width: 100%;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.3/leaflet.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.3/leaflet-src.js"></script>
<div class="button-group">
<button name="entretientLayer">entretient</button>
<button name="sécuritéLayer">sécurité</button>
<button name="secrétariatLayer">secrétariat</button>
</div>
<p></p>
<div id="map"></div>
UPDATE: updated leaflet.js to version 1.3.3.
The difference with the update is that each layer needs to be initialised using the new key word. Code is updated to reflect the change.

Add infowindow and custom icon to Google map using Geojson

I have this simple Google map in a Web2py application.
I would like to apply something like a switch for choosing the feature icon and also setting an infoWindow from json text.
Someone knows how I can do it?
var map;
function initMap() {
map = new google.maps.Map(document.getElementById("events_map"), {
center: {lat: 45.070309, lng: 7.686580999999933},
zoom: 13,
mapTypeControl: false
});
var largeInfowindow = new google.maps.InfoWindow();
google.maps.event.addListener(map, 'idle', function() {
var ne = map.getBounds().getNorthEast();
var north = ne.lat();
var east = ne.lng();
var sw = map.getBounds().getSouthWest();
var south = sw.lat();
var west = sw.lng();
var queryString = '?east=' + east + '&west=' + west + '&south=' + south + '&north=' + north + '&zoom=8'
map.data.loadGeoJson('{{=URL('f_ajax', 'get_locations_g')}}' + queryString);
});
}
json data has a category field that can have 1, 2, 3, or 4 as value.
So with a switch I would like to set the icon in this way:
var icon;
switch (feature.properties.category) {
case '1':
icon = greenIcon;
break;
case '2':
icon = bluIcon;
break;
case '3':
icon = redIcon;
break;
case '4':
icon = blackIcon;
break;
}
But I don't know how.
For the infowindow, can I use this function and how for displaying the json field 'description'?
Thanks.
function populateInfoWindow(marker, infowindow) {
// Check to make sure the infowindow is not already opened on this marker.
if (infowindow.marker != marker) {
infowindow.marker = marker;
infowindow.setContent("<div><a href='" + marker.link + "'>" + marker.title + '</a></div>');
infowindow.open(map, marker);
// Make sure the marker property is cleared if the infowindow is closed.
infowindow.addListener('closeclick', function() {
infowindow.marker = null;
});
}
}
For the icon you have to use the setStyle-function.
A object with the icons should be the easiest approach here
map.data.setStyle(function(feature) {
return {
icon:({1:greenIcon,
2:redIcon,
3:blueIcon,
4:blackIcon})[feature.getProperty('category')]
};
});
The function for the InfoWindow may not be used, because there is no marker available in the click-handler, you have to set the options of the InfoWindow based on the clicked feature
map.data.addListener('click', function(event) {
largeInfowindow.setOptions({
map : map,
position: event.feature.getGeometry().get(),
content : '<strong>'+event.feature.getProperty('description')+'</strong>'
})
});
Demo:
function initMap() {
var greenIcon = 'http://maps.gstatic.com/mapfiles/markers2/icon_green.png',
redIcon = 'http://maps.gstatic.com/mapfiles/markers2/marker.png',
blueIcon = 'http://maps.gstatic.com/mapfiles/markers2/boost-marker-mapview.png',
blackIcon = 'http://maps.gstatic.com/mapfiles/markers2/drag_cross_67_16.png',
map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {lat:52.41, lng: 9.74}
}),
largeInfowindow = new google.maps.InfoWindow({pixelOffset:new google.maps.Size(0,-30)});
map.data.setStyle(function(feature) {
return {
icon:({1:greenIcon,
2:redIcon,
3:blueIcon,
4:blackIcon})[feature.getProperty('category')]
};
});
map.data.addListener('click', function(event) {
largeInfowindow.setOptions({
map : map,
position: event.feature.getGeometry().get(),
content : '<strong>'+event.feature.getProperty('description')+'</strong>'
})
});
map.data.addGeoJson(json);
}
var json={
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {category:1,description:'Berlin'},
"geometry": {
"type": "Point",
"coordinates": [
13.392333984375,
52.53627304145948
]
}
},
{
"type": "Feature",
"properties": {category:2,description:'Hamburg'},
"geometry": {
"type": "Point",
"coordinates": [
10.008544921875,
53.57293832648609
]
}
},
{
"type": "Feature",
"properties": {category:3,description:'Cologne'},
"geometry": {
"type": "Point",
"coordinates": [
6.954345703125,
50.951506094481545
]
}
}
]
};
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<script async defer
src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
<div id="map"></div>

leaflet map, getting specific data of geojson file with button

I'm triying to display on my map specific value ( data.geojson) of my geojson file with buttons. (for exemple to plot a map with only value "domaine":"violences ")
I am loocking for a way to rely my data ("domaine":"violences" or other)with a buttons on my map ?
Thanks so much in advance for your time.
my js:
<script type="text/javascript">
var map = L.map('map');
var terrainTiles = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.{ext}', {
attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap',
subdomains: 'abcd',
minZoom: 0,
maxZoom: 20,
ext: 'png'
});
terrainTiles.addTo(map);
map.setView([46.5160000, 6.6328200], 10);
L.control.locate(location).addTo(map);
function addDataToMap(data, map) {
var dataLayer = L.geoJson(data, {
onEachFeature: function(feature, layer) {
var popupText = "<b>" + feature.properties.nom
+ "<br>"
+ "<small>" + feature.properties.localite
+ "<br>Rue: " + feature.properties.rue + + feature.properties.num
+ "<br>Téléphone: " + feature.properties.tel
+ "<br><a href= '" + feature.properties.url + "'>Internet</a>";
layer.bindPopup(popupText); }
});
dataLayer.addTo(map);
}
$.getJSON("data.geojson", function(data) { addDataToMap(data, map); });
</script>
</body>
</html>
the data.geojson
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ 6.1200622,46.2106091 ]
},
"properties": {
"nom":"Centre d'entraînement aux méthodes d'éducation active - Genève",
"rue":"Route des Franchises",
"num":"11",
"npa":1203,
"localite":"Genève",
"canton":"GE",
"tel":"022 940 17 57",
"url":"www.formation-cemea.ch",
"domaine":"formation "
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ 6.1243056,46.2120426 ]
},
"properties": {
"nom":"VIRES",
"rue":"Rue Ernest-Pictet ",
"num":"10",
"npa":1203,
"localite":"Genève",
"canton":"GE",
"tel":"022 328 44 33",
"url":"www.vires.ch",
"domaine":"violences "
}
}
As for toggling ON / OFF your categories, you could use Leaflet Layers Control L.control.layers.
As for grouping your features by category ("domaine" in your case), see the post I linked in my comment: Leaflet: How to toggle GeoJSON feature properties from a single collection?
You could even slightly simplify it by directly using Layer Groups L.layerGroup instead of using intermediate arrays.
var categories = {},
category;
var layersControl = L.control.layers(null, null).addTo(map);
function addDataToMap(data, map) {
L.geoJson(data, {
onEachFeature: function(feature, layer) {
category = feature.properties.domaine;
// Initialize the category layer group if not already set.
if (typeof categories[category] === "undefined") {
categories[category] = L.layerGroup().addTo(map);
layersControl.addOverlay(categories[category], category);
}
categories[category].addLayer(layer);
}
});
//dataLayer.addTo(map); // no longer add the GeoJSON layer group to the map.
}
$.getJSON("data.geojson", function(data) {
addDataToMap(data, map);
});
Demo: https://plnkr.co/edit/H6E6q0vKwb3RPOZBWs27?p=preview

How to open markers popups on leaflet via external link

Considering a custom floor plan been showed with leaflet with markers loaded from a geojson file. Each of the markers have a related page and those pages have hyperlinks aiming to the map. I would like to add #id to those hyperlinks.
If for example, the map url was domain.com/map, the "Marker 1" page (domain.com/marker-1) would have a link (domain.com/map#maker-1) that would open the map with the actual marker for "marker 1" on the center of the map with it's popup open.
My question is how do I open the map with a certain marker on the center and with it popups open when I add a hash to the url (domain.com/map#maker-1)?
Here goes my code:
index.php
<head>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js" />
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="geojson.js" type="text/javascript"></script>
</head>
<body>
<div id="map"></div>
<script src="map.js"></script>
</body>
geojson.js
var groupsGeoJson = {
"type": "FeatureCollection",
"features":[
{
"geometry": {
"type": "Point",
"coordinates": [-120,60]
},
"type": "Feature",
"properties": {
"popupContent": "<h1>Maker 1</h1>"
},
"id": 1
},
{
"geometry": {
"type": "Point",
"coordinates": [-80,40]
},
"type": "Feature",
"properties": {
"popupContent": "<h1>Maker 2</h1>"
},
"id": 2
}
]
};
map.js
var mapMinZoom = 2;
var mapMaxZoom = 6;
var mapIniZoom = 2;
var mapCenterLat = 20;
var mapCenterLng = -75;
var groupsIcon = L.icon({
iconUrl: 'images/silver_coin.gif',
iconSize: [32, 32],
iconAnchor: [16, 32],
popupAnchor: [0, -28]
});
var baseLayer = new L.TileLayer('layers/baseLayer/{z}/{x}/{y}.png', {
minZoom: mapMinZoom,
maxZoom: mapMaxZoom,
noWrap: true
});
var groups= L.geoJson(groupsGeoJson, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {icon: groupsIcon});
}, onEachFeature: onEachFeature
});
var map = new L.Map('map', {
layers: [baseLayer, groups],
center: new L.LatLng(mapCenterLat, mapCenterLng),
zoom: mapIniZoom
});
var southWest = map.unproject([0, 16384], map.getMaxZoom());
var northEast = map.unproject([16384, 0], map.getMaxZoom());
var mapBounds = new L.LatLngBounds(southWest,northEast);
map.setMaxBounds(mapBounds);
function onEachFeature(feature, layer) {
var popupContent = "<p>Test</p>"
if (feature.properties && feature.properties.popupContent) {
popupContent += feature.properties.popupContent;
}
layer.bindPopup(popupContent);
}

Categories

Resources