I am have a vuejs/nuxtjs application using the gmap-vue package which is a fork of vue-google-maps. I have followed the drawing manager with slot example which is working as shown on the document, good times!
But...
I would like to do two more things
Save the data that I added to the map, how do I access it?
How to load geojson onto the map and then edit it.
Examle below:
More information from further investigation.
I am trying to build up data in the form of geojson
let shapes = [];
for(let shape in this.shapes){
let tmp = {
"type": "Feature",
"properties": {
"id": this.shapes[shape].id || null,
"zIndex": this.shapes[shape].zIndex || null
},
"geometry": {
"type": this.shapes[shape].type,
"coordinates": // where to find shape coordinates?
}
};
shapes.push(tmp)
}
console.log(JSON.stringify(shapes));
displays the following in the console.log
[
{
"type":"Feature",
"properties":{
"id":null,
"zIndex":null
},
"geometry":{
"type":"polygon",
"coordinates": // where to find coordinates?
}
}
]
console.log[this.shapes[shape]];
returns
{__ob__: Observer}
overlay: (...)
type: (...)
How can I access the coordinates?
For anyone else looking for an answer, I hope this helps you out.
const newShapes = [];
this.shapes.forEach((shape) => {
const coords = [];
shape.overlay.latLngs.getArray().forEach((latLng) => {
coords.push([latLng.lat, latLng.lng]);
});
newShapes.push({
type: 'Feature',
geometry: {
type: shape.type,
coordinates: coords,
},
});
});
As shown here: https://diegoazh.github.io/gmap-vue/#getting-a-map-reference
this.$refs.mapRef.$mapPromise.then((map) => {
map.panTo({lat: 1.38, lng: 103.80})
})
is working pretty great.
<gmap-drawing-manager ref="drawingRef">
and
<gmap-drawing-manager :shapes="shapes" ref="drawingRef">
allows to access the same information with this.shapes!
Problem:
I am working on project where I use node.js server that communicate with my spatial DB in PG and my client uses mapbox to vizualize map on his side. After hitting a button, the request is send to server, server to psql, psql to server as result query and then through socket.io back to client, where I want to put my geoJSON / new geometry as new layer on his map after that client buttonclick occurs. Map on client side in HTML is well working and I can interact with it. I use JS inside of HTML page of my client. From there I need to update mapbox map with new geometry after button click.
Code sample:
But I tried this code, but this do nothing after button click and will show no errors in devTool Chrome console:
<script>
mapboxgl.accessToken = 'secretToken-I-have-just-for-ilustr--this-is-working';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v10',
center: [17.10, 48.14], // starting position on Bratislava
zoom: 11 // starting zoom
});
// Add zoom and rotation controls to the map.
map.addControl(new mapboxgl.NavigationControl());
// later SOCKET PROCESSING
$(document).ready(function(){
$('#buttonRun').click(function(e){
map.on('load', function () {
alert("got HERE") // this is working, alert shows itself
map.addLayer({
"id": "route",
"type": "line",
"source": {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-122.48369693756104, 37.83381888486939],
[-122.48348236083984, 37.83317489144141],
[-122.48339653015138, 37.83270036637107],
[-122.48356819152832, 37.832056363179625],
[-122.48404026031496, 37.83114119107971],
[-122.48404026031496, 37.83049717427869],
[-122.48348236083984, 37.829920943955045],
[-122.48356819152832, 37.82954808664175],
[-122.48507022857666, 37.82944639795659],
[-122.48610019683838, 37.82880236636284],
[-122.48695850372314, 37.82931081282506],
[-122.48700141906738, 37.83080223556934],
[-122.48751640319824, 37.83168351665737],
[-122.48803138732912, 37.832158048267786],
[-122.48888969421387, 37.83297152392784],
[-122.48987674713133, 37.83263257682617],
[-122.49043464660643, 37.832937629287755],
[-122.49125003814696, 37.832429207817725],
[-122.49163627624512, 37.832564787218985],
[-122.49223709106445, 37.83337825839438],
[-122.49378204345702, 37.83368330777276]
]
}
}
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#888",
"line-width": 8
}
});
});
});
});
</script>
Even this is not working - even if I set data in click function in a static way, but this data will later change dynamically. If I add that layer out of click event function scope, it is working and layer loads on client map.
Settings / versions:
Windows10 Pro - 64-bit
Google Chrome - Version 69.0.3497.100 (Official Build) (64-bit)
Node.js - v10.11.0
mapbox-gl.js v0.49.0
Q:
Is there any way how to add layer to mapbox map dynamically, please? And later to remove without page refresh? (I still not found answer, even here)
Solution
Okay, I found something I before did not see, concretely this.
I better read documentation, and it is impossible to setup new layers dynamically, but now it is working as follows / you need to:
Out of all scopes define your variables, for example geoJson1, and geoJson2 that you can later edit / fill with function
Setup your layer in advance on map with your ID (as in code below) and fill it for example with goeJson1 or with empty []
In your on click listener function call this: map.getSource('data-update').setData(geojson2);
You just can setup as many layers in advance as you need, and later you can update them.
Code result:
<script>
mapboxgl.accessToken = 'token-from-your-registered-account';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v10',
center: [17.10, 48.14], // starting position on Bratislava
zoom: 11 // starting zoom
});
var geojson = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.48369693756104, 37.83381888486939],
[-122.48348236083984, 37.83317489144141],
[-122.48339653015138, 37.83270036637107],
[-122.48356819152832, 37.832056363179625],
[-122.48404026031496, 37.83114119107971]
]
}
}]
};
var geojson2 = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.48369693756104, 37.83381888486939],
[-122.48348236083984, 37.83317489144141],
[-122.48339653015138, 37.83270036637107],
[-122.48356819152832, 37.832056363179625],
[-122.48404026031496, 37.83114119107971],
[-122.48404026031496, 37.83049717427869],
[-122.48348236083984, 37.829920943955045],
[-122.48356819152832, 37.82954808664175],
[-122.48507022857666, 37.82944639795659],
[-122.48610019683838, 37.82880236636284],
[-122.48695850372314, 37.82931081282506],
[-122.48700141906738, 37.83080223556934],
[-122.48751640319824, 37.83168351665737],
[-122.48803138732912, 37.832158048267786],
[-122.48888969421387, 37.83297152392784],
[-122.48987674713133, 37.83263257682617],
[-122.49043464660643, 37.832937629287755],
[-122.49125003814696, 37.832429207817725],
[-122.49163627624512, 37.832564787218985],
[-122.49223709106445, 37.83337825839438],
[-122.49378204345702, 37.83368330777276]
]
}
}]
};
map.on('load', function () {
map.addLayer({
"id": "data-update",
"type": "line",
"source": {
"type": "geojson",
"data": geojson // your previously defined variable
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#888",
"line-width": 8
}
});
});
$(document).ready(function(){
$('#buttonRun').click(function(e){
map.getSource('data-update').setData(geojson2);
});
});
</script>
I am trying to take the JSON from an API call, parse it in to a GeoJSON array (just taking the lat, long and name variable) and then load it in to a Leaflet map.
I am getting no errors in the console. The geojson is loading in to the map but it is empty. When i query it (console.log(geojson) it appears empty. For some reason my function is failing to correctly parse in to the geojson.
var map1 = L.map('map').setView([52.599043, -1.325812], 6);
var OpenStreetMap_Mapnik = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map1);
var ports = $.ajax({
url:"API_URL",
dataType: "json",
success: console.log("County data successfully loaded."),
})
var geojson = {
type: "FeatureCollection",
features: [],
};
for (var i in ports.data) {
geojson.features.push({
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ports.data[i].longitude, ports.data[i].latitude]
},
"properties": {
"stationName": ports.data[i].port_name
}
});
}
L.geoJSON(geojson).addTo(map1);
Following Andreas's comment I looked in to Asynchronous AJAX.
I ended up restructuring my code to ensure that the processing of the response was done after the ajax call was completed:
I nested the processing of API response in a function that used the output from the API call. The API call has a function that runs when it's successful that passes the response to the processing function.
function callback1(response) {
var geojson = {
type: "FeatureCollection",
features: [],
};
for (var i in response.data) {
geojson.features.push({
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [response.data[i].longitude, response.data[i].latitude]
},
"properties": {
"stationName": response.data[i].port_name
}
})};
L.geoJSON(geojson, {onEachFeature:Ports_Popup}).addTo(map1);
console.log(response);
};
$.ajax({
url:"https://statistics-api.dft.gov.uk/api/ports?filter[country]=scotland",
dataType: "json",
success: function(response){
callback1(response)
}})
My code is this
heat = L.heatLayer([], { maxZoom: 12 }).addTo(map);
$.getJSON("js/example-single.geojson", function(data) {
var geojsosn = L.geoJson(data, {
onEachFeature: function (feature, layer) {
console.log(feature.geometry.coordinates[0] ,feature.geometry.coordinates[1]);
heat.addLatLng(feature.geometry.coordinates[0], feature.geometry.coordinates[1]);
}
});
but am getting an error "Uncaught TypeError: Cannot read property 'lat' of undefined"
please tell how to fix this, if my code is wrong somebody show me how to parse json data for heat map in mapbox
my json data is
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [13.353323936462402, 38.11200434622822]},
"properties": {"marker-color": "#000"}
}
]
}
addLatLng probably expects L.latLng objects or something that has lat & lng properties.
var heat = L.heatLayer([], { maxZoom: 12 }).addTo(map);
$.getJSON('js/example-single.geojson', function(data) {
var geojson = L.geoJson(data, {
onEachFeature: function(feature, layer) {
feature.geometry.coordinates.forEach(function(p) {
heat.addLatLng(L.latLng(p[0], p[1]));
});
}
});
});
I have large json file and I am working to plot it on map. I can't load the file, that why I have to request data every time I zoom in or move the map
The file is
var data3d = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[13.37356, 52.52064],
[13.37350, 52.51971],
[13.37664, 52.51973],
[13.37594, 52.52062],
[13.37356, 52.52064]
]]
},
"properties": {
"wallColor": "rgb(255,0,0)",
"height": 500
}
},{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[13.37356, 52.52064],
[13.37350, 52.51971],
[13.37664, 52.51973],
[13.37594, 52.52062],
[13.37356, 52.52064]
]]
},
"properties": {
"wallColor": "rgb(255,0,0)",
"height": 500
}
}]
};
I wanna build a function that filter data that I need to plot
function onMapMove(e) { requestData(); }
Then I should build a function this way.
function requestData() {
var bounds=map.getBounds(); // I get these values from the browser
var minLongitudeLat=bounds.getSouthWest(); //minimum Longitude Latitude
var maxLongitudeLat=bounds.getNorthEast(); //maximum Longitude Latitude
// Here what I should to select data between
['+minLongitudeLat.lat+','+minLongitudeLat.lng+'],['+maxLongitudeLat.lat+','+maxLongitudeLat.lng+'];
}
should I write JQuery PostJson function.
jQuery.postJSON(link,
function(data){
return //
});
UPDATE: (Answer Comment)
I am trying to build ajax call,
thisFile.json is the file that contain abovemontioned data3 content
$.ajax({
url: 'thisFile.json',
data: 'GET',
dataType: 'json',
success: function(data){
filteredData=[]
for (var i = data.features.length - 1; i >= 0; i--) {
if((data.features[i].["geometry"]["coordinates"][0][0]>minLongitudeLat.lat &&
data.features[i].["geometry"]["coordinates"][0][1] <minLongitudeLat.lng ) &&
(data.features[i].["geometry"]["coordinates"][0][0] > maxLongitudeLat.lat &&
data.features[i].["geometry"]["coordinates"][0][1]< maxLongitudeLat.lng)) {filteredData.append(filteredData) }
return filteredData;
};
},
});
or should I write python script to make the filtering
PythonScript.py , but how to get and post data ?
import json
print "Content-type: application/json"
// Should I read here the whole data
// local_file = open("/tmp/download_file.json", "w")
// How to pass parameters to filter json file ?
print json.dumps()
$.getJSON("/PythonScript.py ", function(data) {
// Here we get data
});