Django - How to display GeoJSON on a Mapbox map? - javascript

Using Django (v1.11) and Mapbox, I am trying to display a map with some GeoJSON content which I load from a local file. For example purposes I am using this sample.json file.
My idea was to load the GeoJSON file into a JSON object, and pass that to a template (in this case map.html). Additionally, I attempted to convert the JSON object into a string, pass that string, and then re-create a new JSON object with Javascript (shown below). Neither method has worked for me.
However, if I simply copy-paste the contents of sample.json as a Javascript variable, everything works and the GeoJSON is displayed correctly.
So my question is, how can I load the GeoJSON from a file, pass that to an HTML template, and then display the contents on a Mapbox map?
views.py
def get(self, request, *args, **kwargs):
with open('/somepath/sample.json') as f:
data = json.load(f)
data = json.dumps(data)
return render(request, 'map.html', {'data':data})
map.html
map.on('load', function () {
// THIS DOES NOT WORK
var json_data = JSON.parse({{ data }})
map.addLayer({
'id': 'layerid',
'type': 'fill',
'source': {
'type': 'geojson',
'data': json_data
}
});
});
map.html
map.on('load', function () {
// THIS WORKS
var json_data = { "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
"properties": {"prop0": "value0"}
},
{ "type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
]
},
"properties": {
"prop0": "value0",
"prop1": 0.0
}
},
{ "type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
[100.0, 1.0], [100.0, 0.0] ]
]
},
"properties": {
"prop0": "value0",
"prop1": {"this": "that"}
}
}
]
}
map.addLayer({
'id': 'layerid',
'type': 'fill',
'source': {
'type': 'geojson',
'data': json_data
}
});
});
EDIT
I have also now tried:
views.py
def get(self, request, *args, **kwargs):
return render(request, 'map.html', {'path':'/somepath/sample.json'})
map.html
map.on('load', function () {
// THIS DOES NOT WORK
$.getJSON({{ path }}, function(data) {
var json_data = data
});
map.addLayer({
'id': 'layerid',
'type': 'fill',
'source': {
'type': 'geojson',
'data': json_data
}
});
});

Related

Is there any way to update my mapbox gl source?

Hello i have a problem when i try to update my mapbox source on click.
I have already to sources (cells , heatmap), I try to add a new sources with these code
this.map.addSource("points", {
type: "geojson",
data: {
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.0323, 38.9131],
},
properties: {
title: "Mapbox DC",
"marker-symbol": "monument",
},
},
});
I also try delele sources (cells , heatmap), add then a dd a new sources.
this.map.removeLayer("heatmap");
this.map.removeSource("heatmap");
this.map.removeLayer("cells");
this.map.removeSource("cells");
this.map.addSource("points", {
type: "geojson",
data: {
type: "Feature",
geometry: {
type: "Point",
coordinates: [-77.0323, 38.9131],
},
properties: {
title: "Mapbox DC",
"marker-symbol": "monument",
},
},
});
I don't get any error in the browser console from mapbox but i cant see the new sources.
Thanks a lot !
I find the solution i have wrong coordinates ( i have lat,lot but we want lot,lat) –

MapBox web app map widget, Multiple 'paint' arguments. Adding Opacity and Radius fails

I would like to combine the following two arguments in a mapbox webapp widget.
The first argument is the color of latitude and longitude points:
I also want to have the opacity argument added, so the map dots do not have a center, like this:
But when I try to add both arguments, the opacity argument is ignored.
var coorAddresses = [ [ -75.7040473, 45.418067,"Medium" ], [-75.7040473, 45.418067, "Medium"], [-79.32930440000001, 43.7730495, "Unknown"]]
$.getJSON(coodAddresses, function(data) {
for(var itemIndex in data) {
// push new feature to the collection
featureCollection.push({
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [data[itemIndex][0], data[itemIndex][1]]
},
"properties": {
"size_by": data[itemIndex][2],
"color_by": data[itemIndex][2]
},
});
}
});
map.on('load', function () {
map.addLayer({
"id": "points",
"type": "circle",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": featureCollection
}
},
"paint": {
"circle-color": [
'match',
['get', 'size_by'],
'Easy',
'#e4f400',
'Medium',
'#f48a00',
'Unknown',
'#6af400',
/* other */ '#00e4f4'
],
"circle-radius": [
'match',
['get', 'size_by'],
'Easy',
4,
'Medium',
7,
'Unknown',
2,
/* other */ 1000
],
// "circle-opacity": 0, // color does not show if i uncomment these lines
// "circle-stroke-width": 1, // do not get desired 'hollow' circle unless these lines run
}});

Mapbox GL JS cannot load GeoJson from path

I'm writing the app in Ruby on Rails and I have the application set to serve GeoJson from a specific path. What I would like to do have Mapbox grab the GeoJson from the specified path, and add it to the map. Here is my javascript code to create the map
$(document).on 'turbolinks:load', ->
map = new (mapboxgl.Map)(
container: 'map'
style: 'mapbox://styles/mapbox/streets-v9'
zoom: 6
)
map.on 'load', ->
map.addSource 'shapes',
type: 'geojson'
data: '/regions.json'
When I navigate to /regions.json I get the following response.
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {},
"geometry": {
"coordinates": [
[
[8.66990129597281, 50.1242808292475],
[8.6629978834745, 50.1232734203388],
[8.66073109130571, 50.1231247844397],
[8.65846429911693, 50.1231743297949],
[8.65887644316587, 50.1218035561855],
[8.65993256224607, 50.1193096384939],
[8.65980376723581, 50.1190949242805],
[8.66297212445633, 50.1181699904754],
[8.66451766457959, 50.1175093125293],
[8.6669905287728, 50.1165843480906],
[8.66910276691314, 50.1158080248614],
[8.67085437906084, 50.1154611529673],
[8.67098317407113, 50.1174597613236],
[8.67077710204663, 50.1200363564073],
[8.67015888599337, 50.1224806902187],
[8.66979825998064, 50.1237358401687],
[8.66990129597281, 50.1242808292475]
]
],
"type": "Polygon"
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"coordinates": [
[
[8.69901780003497, 50.1216735191773],
[8.69820854586041, 50.1210834384206],
[8.69762143988481, 50.1207476995652],
[8.69625681516334, 50.1199134291953],
[8.6948921904667, 50.1181736234834],
[8.69597119603273, 50.1173698322427],
[8.69612987332479, 50.1173291335912],
[8.69676458249296, 50.1181736234834],
[8.69744689485361, 50.1188553092786],
[8.69879565183601, 50.1200558666313],
[8.70008093788664, 50.121042742926],
[8.69901780003497, 50.1216735191773]
]
],
"type": "Polygon"
}
}, {
"type": "Feature",
"properties": {},
"geometry": {
"coordinates": [
[
[8.67778012178596, 50.105440710563],
[8.67960973428302, 50.103294069223],
[8.67505801538456, 50.1017054926895],
[8.67414320915341, 50.1013763215998],
[8.66892211982668, 50.0993583102266],
[8.66816350002185, 50.1000882390455],
[8.6691229309412, 50.1009755885121],
[8.67238053367137, 50.1029076635563],
[8.67427708321821, 50.1039953159691],
[8.67778012178596, 50.105440710563]
]
],
"type": "Polygon"
}
}]
}
The map loads just fine, but there are no shapes. The frustrating part is that there are no errors in the browser, and that the GeoJson checks out on geojson.io.
What am I doing wrong here?
Ok so it turns out what I actually wanted to do was create a layer and assign the remote GeoJson file as the source:
map.addLayer
id: 'territory-map'
type: 'fill'
source:
type: 'geojson'
data: '/regions.json'
I was able to find an example of this process here

Ajax not firing after I added a GeoJson 'data'

I have an HTML page where a button click will fire an ajax function showDetail():
<a href="#" class="list-group-item" onclick="showDetail({{ test.id }});">
<strong>{{ test.test_name }}</strong></a>
The ajax function works well if it's like this on its own:
function showDetail(id){
$.ajax({
url : "/test/" + id,
type: 'GET',
success: function(data){
map.removeLayer(tests);
$('#pane-content-edit').html(data);
$('.tests_display').animate({right:0});
}
});
}
I would like to modify it having the current HTML page containing a Geojson. And I'd like to pass it to my ajax to pass it to the url my ajax is pointing at. So I did this:
function showDetail(id){
$.ajax({
url : "/test/" + id,
type: 'GET',
data: {'tests_geojson' : {{ tests_geojson | safe}}},
success: function(data){
map.removeLayer(tests);
$('#pane-content-edit').html(data);
$('.tests_display').animate({right:0});
}
});
}
After adding that, it would not fire. I tried opening up the web console, nothing is happening. Can someone help? or tell me how to debug this?
Thank you!
Edit:
Additional info - Django Framework templating
Contents of test_geojson showing on Leaflet map so it's most likely validated: Big geojson feature but would look generally like so:
alert(JSON.stringify(geojsonFeature));
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
"properties": {"prop0": "value0"}
},
{ "type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
]
},
"properties": {
"prop0": "value0",
"prop1": 0.0
}
}
]
}
Edit: Temporary Solution
This looks like on the right direction. Serializing the JSON data to string, adding csrf, then modify things at views.py. However an error occurs, saying that it has exceeded Data Upload Max Memory Size so I had to set DATA_UPLOAD_MAX_MEMORY_SIZE = None which is a security no-no. If someone has a better workaround it'll be helpful!
var geojsonFeature = {{tests_geojson|safe}};
function showDetail(id){
$.ajax({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
url : "/test/" + id,
type: 'POST',
data: {'tests_geojson' : JSON.stringify(geojsonFeature)},
success: function(data){
map.removeLayer(tests);
$('#pane-content-edit').html(data);
$('.tests_display').animate({right:0});
}
});
}

Zoom in not working on Highmaps

I took a Highmaps example from the demo section and zooming in was working fine. Then I replaced the data object with my own data and changed the world map with my own GeoJSON data.
Now the zoom doesn't work anymore.
Please see this JSFiddle.
I managed to simplify the code up to this point:
var geoJson = { ... }
var data = [...]
// Initiate the chart
$('#container').highcharts('Map', {
mapNavigation: {
enabled: true,
navigationButtons: true
},
colorAxis: {
min: 1,
max: 1000,
type: 'logarithmic'
},
series: [{
data: data,
mapData: geoJson,
joinBy: ['name', 'name'],
}]
});
What can I do to make the zoom work?
This must be a bug, it works if you change your coordinate data. jsFiddle:
var geoJson = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"name": "a"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[3125, 6250],
[5625, 6250],
[5624, 8750],
[3125, 8750],
[3125, 6250]
]
]
}
}, {
"type": "Feature",
"properties": {
"name": "b"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[6875, 6250],
[9375, 6250],
[9375, 8750],
[6875, 8750],
[6875, 6250]
]
]
}
}]
};
// Initiate the chart
$('#container').highcharts('Map', {
mapNavigation: {
enabled: true,
},
series: [{
mapData: geoJson
}]
});
I suggest filing an issue on GitHub, and we'll look into it in detail.

Categories

Resources