Openlayers 3 : popup by geojson file - javascript

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.

Related

getting Uncaught Error: Invalid LatLng object: (NaN, NaN) when trying to display points from geojson

I tried to display the point from geojson but there is an error that I mentioned above. this is my source code
maps.setView(new L.LatLng(-8.203824, 113.175476), 12);
L.geoJson(dataPelanggan, {
pointToLayer: function(feature, latlng) {
console.log(feature)
return L.marker(latlng, {
icon: L.icon({
iconUrl: 'asset/img/marker.png',
iconSize: [38, 45]
})
});
},
onEachFeature: function(feature, layer) {
if (feature.properties && feature.properties.popUp) {
layer.bindPopup(feature.properties.popUp);
}
}
}).addTo(maps);
I'm using leaflet version 0.7.7 because there is some kind of source code algorithm that I use using that version, then I want to add this point to clarify the function of the feature that I created. can someone help me? sorry if my sentence is confusing.
geojson got from api
var dataPelanggan=[
{
"type": "Feature",
"properties": {
"jenis": "Pelanggan",
"nosambungan": "519",
"nama": "CHU",
"alamat_pelanggan": "TEMPEH LOR",
"Stan": "96",
"popUp": "No. Sambungan : 519<br>Nama : CHU<br>Alamat : TEMPEH LOR<br>Stan : 96"
},
"geometry": {
"type": "Point",
"coordinates": [
"113.177157376778350",
"-8.196966314315622"
]
}
},
{
"type": "Feature",
"properties": {
"jenis": "Pelanggan",
"nosambungan": "5110",
"nama": "NUR",
"alamat_pelanggan": "TEMPEH",
"Stan": "125",
"popUp": "No. Sambungan : 5110<br>Nama : NURY<br>Alamat : RAYA TEMPEH LOR<br>Stan : 125"
},
"geometry": {
"type": "Point",
"coordinates": [
"113.177076511097520",
"-8.197180194910073"
]
}
},

Using OpenLayers, how can I display different icons for different features on a single layer?

firstly I'm new to Openlayers/JS as a whole and fairly inexperienced with programming in general so there might be other problems with my code that I'm not aware of.
I am using the latest version of Openlayers (5.3.0).
My program currently passes GeoJson formatted data via Ajax to be displayed on an Openlayers map. It creates the map, view and a layer for the features to be displayed on. When I press a "Go" button on the page, the features are loaded onto the map successfully. In my case the features are just simple points with latitude/longitude using a png marker to visualise. The GeoJson looks like this in C# before being serialised and sent to JS on my page for deserialisation:
{{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-1.549077,
53.800755
]
},
"properties": {
"GPSKey": 1,
"Latitude": 53.800755,
"Longitude": -1.549077,
"TimeAdded": "2019-01-15T12:10:16",
"IconPath": "pinred.png"
},
"ID": 1,
"IconPath": null
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-1.545077,
53.800755
]
},
"properties": {
"GPSKey": 2,
"Latitude": 53.800755,
"Longitude": -1.545077,
"TimeAdded": "2019-01-15T12:10:16",
"IconPath": "pinred.png"
},
"ID": 2,
"IconPath": null
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-1.524043,
53.773222
]
},
"properties": {
"GPSKey": 3,
"Latitude": 53.773222,
"Longitude": -1.524043,
"TimeAdded": "2019-01-15T12:10:16",
"IconPath": ""
},
"ID": 3,
"IconPath": null
}
]
}}
The JS receives the above serialised and uses this code to add it to the layer for viewing:
var geojsonFormat = new ol.format.GeoJSON({
dataProjection: "EPSG:4326",
featureProjection: "EPSG:3857"
});//creates a format definition
jsonDecoded = JSON.parse(result); /
if (jsonDecoded.features.length > 0) {
for (var i = 0; i < jsonDecoded.features.length; i++) {
vectorSource.addFeature(geojsonFormat.readFeature(jsonDecoded.features[i], { featureProjection: "EPSG:3857" }));
}
}/
The vector layer it gets added to looks like this:
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyleFunc()
});
And the iconStyleFunc() looks like this:
function iconStyleFunc() {
var zIndex = 1;
var iconName = null;
if (iconName == null) {
iconName = "pinother.png"
};
iconStyle = [new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 36],
anchorXUnits: "fraction",
anchorYUnits: "pixels",
opacity: 1,
src: "images/" + iconName,
zIndex: zIndex
})),
zIndex: zIndex
})];
return iconStyle;
This works fine for styling all the features with the icon "pinother.png". I have no problem displaying the points on the map when I press the button.
What I'd like to do is apply styling based on the icon path in the properties of each feature's GeoJson "iconpath", so that any feature having a "pinred.png" would use that instead of the default "pinother.png", and so on with various icons I might need to add in the future.
I'm not sure how to read this property of each feature and how I would best implement it in the styling function. The way I envisaged it was iterating through features using the iconStyleFunc(), reading the IconPath property for each feature, appending that value to the "src/images/" path in the iconStyleFunc() and styling the feature appropriately.
Using the feature argument of the style function you can get properties of the feature
function iconStyleFunc(feature) {
var zIndex = 1;
var iconName = feature.get("IconPath") || "pinother.png";
iconStyle = [new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 36],
anchorXUnits: "fraction",
anchorYUnits: "pixels",
opacity: 1,
src: "images/" + iconName,
zIndex: zIndex
})),
zIndex: zIndex
})];
return iconStyle;

How can I display multiple MapBox maps on a Squarespace page?

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>

Leaflet: How to style 2000+ points in a GeoJSON object with no style properties?

I have a single GeoJSON FeatureCollection object that contains over 2000 features. In the GeoJSON object, each feature is part of one category like so:
{
"type": "Feature",
"properties": {
"category": "Electrical",
"Name": "Plane No 2"
},
"geometry": {
"type": "Point",
"coordinates": [
94.5703125,
58.722598828043374
]
}
},
{
"type": "Feature",
"properties": {
"category": "Military",
"Name": "Base 1"
},
"geometry": {
"type": "Point",
"coordinates": [
104.4140625,
62.91523303947614
]
}
},
In my actual data, there are a total of about 38 categories (each feature is only assigned to one category).
Is using a JavaScript Switch Statement in my situation a practical solution in order to give each point its own styling? Or, is there a better way?
I am doing something like this in my code:
L.geoJson(mygeoJson, {
onEachFeature: function (feature, layer){
layer.bindPopup(L.Util.template(popupTemplate, feature.properties));
},
pointToLayer: function (feature, latlng){
return L.circleMarker(latlng, gjsonOptions);
},
// 3 of the 38 categories are listed here as an example
style: function(feature){
switch(feature.properties.category){
case 'Electrical': return { color: '#fb8072'};
case 'Military': return { color: '#b3de69'};
case 'Aviation': return { color: '#80b1d3'};
}
}
}).addTo(map);
Demo link here
I think one should add the colors on the clientside, just as he/she did in the code example. adding the colors to each GeoJSON feature will needlessly bloat your transfer. If you really want to add them to your collection you could create some sort of legend property in your collection object like so:
var collection = {
"type": "FeatureCollection",
"properties": {
"legend": {
"Electrical": "#fb8072",
"Military": "#b3de69",
"Aviation": "#80b1d3"
}
}
"features": [...]
}
So that when you create your GeoJSON layer you can add them on the fly:
L.geoJson(collection, {
'style': function (feature) {
return {
'color': collection.properties.legend[feature.properties.category]
}
}
}).addTo(map);
You could instead of storing the legend in the collection object, store it in your code/script somewhere:
var legend = {
"Electrical": "#fb8072",
"Military": "#b3de69",
"Aviation": "#80b1d3"
}
L.geoJson(collection, {
'style': function (feature) {
return {
'color': legend[feature.properties.category]
}
}
}).addTo(map);
Edit after comments:
If you need to set L.Marker icons you should use the pointToLayer function:
L.geoJson(collection, {
'pointToLayer': function (feature, latlng) {
return new L.Marker(latlng, {
'icon': new L.Icon({
'iconUrl': 'icons/' + feature.properties.category + '.png'
...
})
})
}
}).addTo(map);
You're currently using L.CircleMarker which doesn't support the icon option. It's a path which only supports the pathoptions:
http://leafletjs.com/reference.html#path-options
Here's a nice tutorial on creating L.Marker's with custom icons:
http://leafletjs.com/examples/custom-icons.html

google Maps Javascript V3.21 trouble displaying geoJSON features

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>

Categories

Resources