Mapbox non-geographic - popup

I'm trying to mixed up for at least a week , mapbox with leaflet to did a Non geographic map.
My first step was to build it with maptiler.com which generated with the tiled a code based on leaflet. But i want to add to this code a Geojson proprites.
I saw that in Mapbox there is already a geojson popup built-in.
This is why i want to use my leaflet map code + mapbox popup, it's possible ?
Thanks,
Jade
<!DOCTYPE html>
<html>
<head>
<title>map</title>
<meta charset="utf-8"/>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.js'></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js"></script>
<link href='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.css' rel='stylesheet' />
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<!--[if lte IE 8]>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.ie.css" />
<![endif]-->
<script>
L.mapbox.accessToken = 'pk.eyJ1IjoiamFkZTIyOTMiLCJhIjoiRDdweEFrZyJ9.Yk4XeNmp3SExkU41Z7BU3w';
function init() {
var mapMinZoom = 3;
var mapMaxZoom = 6;
var map = L.map('map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
crs: L.CRS.Simple
}).setView([0, 0], mapMaxZoom);
var mapBounds = new L.LatLngBounds(
map.unproject([0, 7680], mapMaxZoom),
map.unproject([10496, 0], mapMaxZoom));
map.fitBounds(mapBounds);
L.tileLayer('{z}/{x}/{y}.png', {
minZoom: mapMinZoom, maxZoom: mapMaxZoom,
bounds: mapBounds,
noWrap: true
}).addTo(map);
// The GeoJSON representing a point feature with a property of 'video' for the Vimeo iframe
var geoJson = {
features: [{
type: 'Feature',
properties: {
'marker-color': '#f00',
'marker-size': 'large',
'marker-symbol': 'rocket',
video: '<iframe src="//player.vimeo.com/video/106112939" width="380" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> <p><h2>How Simplicity Will Save GIS</h2><p>Vladimir Agafonkin from FOSS4G on Vimeo.</p>',
},
geometry: {
type: 'Point',
coordinates: [0,0]
}
}]
};
var myLayer = L.mapbox.featureLayer().addTo(map);
// Add the iframe in a marker tooltip using the custom feature properties
myLayer.on('layeradd', function(e) {
var marker = e.layer,
feature = marker.feature;
// Create custom popup content from the GeoJSON property 'video'
var popupContent = feature.properties.video;
// bind the popup to the marker http://leafletjs.com/reference.html#popup
marker.bindPopup(popupContent,{
closeButton: false,
minWidth: 320
});
});
// Add features to the map
myLayer.setGeoJSON(geoJson);
}
</script>
<style>
html, body, #map { width:100%; height:100%; margin:0; padding:0; }
background-color:white;
</style>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>

It seems that you're asking 2 separate questions here. The original question about non-geographic maps and your follow-up question about adding an iframe to a leaflet popup. I'll try to address your follow-up question:
Let's take the Mapbox example you linked (https://www.mapbox.com/mapbox.js/example/v1.0.0/video/) and adapt it to work with the video you would like to display.
If you've already got some GeoJSON data, you can edit it to include a video property. Let's look at the GeoJSON code from the Mapbox example:
var geoJson = {
features: [{
type: 'Feature',
properties: {
'marker-color': '#f00',
'marker-size': 'large',
'marker-symbol': 'rocket',
video: '<iframe src="//player.vimeo.com/video/106112939" width="380" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> <p><h2>How Simplicity Will Save GIS</h2><p>Vladimir Agafonkin from FOSS4G on Vimeo.</p>',
},
geometry: {
type: 'Point',
coordinates: [0,0]
}
}]
};
See that video property? Its value contains the iframe code that will end up inside the popup for the map marker it corresponds to. I went ahead and added the iframe code from your YouTube video to the above example and you can see it in action on jsfiddle here: http://jsfiddle.net/danswick/tcxvpw84/.
Your GeoJSON data probably doesn't have a video property, but you can add it using a text editor or geojson.io.
Further down in our example code, we access that video property, set it to a variable, and bind it to our marker's popup:
// Create custom popup content from the GeoJSON property 'video'
var popupContent = feature.properties.video;
// bind the popup to the marker http://leafletjs.com/reference.html#popup
marker.bindPopup(popupContent,{
closeButton: false,
minWidth: 320
});

Mapbox just uses Leaflet's bindPopup method which comes standard with L.Marker. If you create a L.GeoJSON layer, you can add a popup to each feature using the onEachFeature option of L.GeoJSON which takes a function with two parameters: feature and layer. In there you can bind a popup to your feature:
For example when you have features like this one, with a property called name:
{
"type": "Feature",
"properties": {
"name": "E"
},
"geometry": {
"type": "Point",
"coordinates": [0, 0]
}
}
You could then use that name value when binding a popup to your feature like this:
// Create new GeoJSON layer
L.geoJson(data, {
// Define the onEachFeature function which runs on every feature
onEachFeature: function (feature, layer) {
// Bind a popup to the layer using the name property
layer.bindPopup(feature.properties.name);
}
}).addTo(map);
Here's a working example on Plunker: http://plnkr.co/edit/iPLHqi?p=preview

Thanks, to take time to reply.
But actually i wanted to use geojson just to put iframe in a leaflet popup.
like this :
L.marker(map.unproject([452, 410])).addTo(map).bindPopup("<iframe width="560" height="315" src="https://www.youtube.com/embed/zP71_cXfiu0" frameborder="0" allowfullscreen></iframe>");
But it doesn't work but with the same syntax this work : I just saw in this exemple that with geojson it's might work :
https://www.mapbox.com/mapbox.js/example/v1.0.0/video/
L.marker(map.unproject([452, 410])).addTo(map).bindPopup("https://www.youtube.com/embed/zP71_cXfiu0");
Sorry if i'm a little bit confusing, because i'm designer and all this "code thing" it's new for me :)

Related

Leaflet lowest zoom level is still too high with L.CRS.Simple

Trying to retrieve part of a district, however for some reason cannot see the whole area, even if zoom level is at 0, where (supposedly) we should see the whole world.
I am using L.CRS.Simple because this uses the EPSG:3763 and cannot see that one on the CRS list. I am retrieving the data in JSON cause when tying with geoJSON, was not able to transform the 3D coordinates data into 2D planes ones.
const queryRegionText = "where=OBJECTID > 0"
const geoJsonURL2 = "https://sig.cm-figfoz.pt/arcgis/rest/services/Internet/MunisigWeb_DadosContexto/MapServer/2/query?f=json&returnGeometry=true&geometryType=esriGeometryPolyline&spatialRel=esriSpatialRelIntersects&outFields=*&outSR=3763&" + queryRegionText
var map = L.map('mapid', {
crs: L.CRS.Simple
}).setView([-58216.458338, 42768.347232], 0);
L.control.scale({ metric: true }).addTo(map);
fetch(geoJsonURL2).then(function (response) {
response.json().then(function (data) {
data.features.forEach(element => {
if (element.geometry.rings) {
element.geometry.rings.forEach(point => {
L.polyline(point, { color: 'red' }).addTo(map);
})
}
});
});
});
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
<html>
<head>
<title>Leaflet - testing</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
</head>
<body>
<div id="mapid" style="width: 600px; height: 400px;"></div>
</body>
</html>
TL;DR: When creating the map, set the minimum zoom below zero. This should work:
var map = L.map('mapid', {
crs: L.CRS.Simple, minZoom: -6
}).setView([-57728, 55296], -6);
Explanation
Normally, Leaflet translates from a latitude/longitude coordinate system to screen pixels using an assumption that the world is 256 pixels high at Zoom level 0. At each higher Zoom Level, the number of pixels doubles (explained nicely in the Zoom levels tutorial). With this assumption, the options for the map default to {minZoom: 0, maxZoom: Infinity} (as you are not adding any Layer that sets these values to anything different).
When you use L.CRS.Simple, at Zoom level 0 it maps 1 coordinate unit to 1 screen pixel. Your data looks like it is about 18000 coordinate units tall, so it doesn't fit in your 400 pixel high map. To make it fit, we need each screen pixel to map to about 45 coordinate units. 2^5 is 32, and 2^6 is 64, so we need to zoom out between 5 and 6 times. Luckily, Leaflet accepts negative Zoom Levels, so setting zoom to -6 does the trick. But to make it work properly, you need to set {minZoom: -6}, so the map doesn't get stuck at zoom level 0. There's a good worked example in the Non-geographical Maps tutorial.
Using L.CRS.Simple should work for you, so long as the approximation holds that each latitude unit is the same length as each longitude unit (a square world). Since this isn't generally true in the real world, using the Simple projection will cause some distortion. If the distortion is significant for the features you are interested in, then you will need to look up how to use EPSG:3763 properly, using L.CRS and Proj4Leaflet, as suggested by #IvanSanchez.
So, after some reading on the proj4leaflet, come up with this code. Thanks in advance for the comments and the reply above.
const queryRegionText = "where=OBJECTID > 0"
const geoJsonURL2 = "https://sig.cm-figfoz.pt/arcgis/rest/services/Internet/MunisigWeb_DadosContexto/MapServer/2/query?f=geojson&returnGeometry=true&geometryType=esriGeometryPolyline&spatialRel=esriSpatialRelIntersects&outFields=*&outSR=3763&" + queryRegionText
const map = L.map('map', {
center: [40.14791, -8.87009],
zoom: 13
});
proj4.defs("EPSG:3763", "+proj=tmerc +lat_0=39.66825833333333 +lon_0=-8.133108333333334 +k=1 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs");
fetch(geoJsonURL2).then(function (response) {
response.json().then(function (data) {
L.Proj.geoJson(data).addTo(map);
});
});
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<link rel="stylesheet" href="main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.7.4/proj4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4leaflet/1.0.2/proj4leaflet.js"></script>
</head>
<body class="">
<div id="map" style="width: 600px; height: 400px;"></div>
</div>
<script src="main.js"></script>
</body>

ArcGIS JavaScript API Popup Not Referencing REST Service Layer

The content in the popup created through the variable "popupCustom" is displaying string instead of referencing the specified field {IN_COUNTRY}. I followed the ArcGIS JS API Popup Tutorials, & can't see what my error is in failing to grab the attributes associated with that field. Here's the code -- any help is greatly appreciated!
*note: feature layer url within "Cyber_Areas" variable points to REST URL for referenced Feature Class.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Search widget with multiple sources - 4.6</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.6/esri/css/main.css">
<script src="https://js.arcgis.com/4.6/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/widgets/BasemapToggle",
"esri/widgets/Legend",
"esri/layers/TileLayer",
"esri/layers/FeatureLayer",
"esri/widgets/Search",
"esri/widgets/LayerList",
"esri/PopupTemplate",
"dojo/on",
"dojo/domReady!"
], function(
Map,
MapView,
BasemapToggle,
Legend,
TileLayer,
FeatureLayer,
Search,
LayerList,
PopupTemplate,
on
) {
var Cyber_Areas = new FeatureLayer({
url: "*inserturl*",
outFields: ["IN_COUNTRY"],
popupTemplate: popupCustom
});
var map = new Map({
basemap: "osm"
});
map.add(Cyber_Areas);
var view = new MapView({
container: "viewDiv",
map: map,
center: [-87.172865, 34.077613], // lon, lat
zoom: 16
});
var searchWidget = new Search({
view: view,
popupOpenOnSelect: false
});
view.ui.add(searchWidget, {
position: "top-left",
index: 0
});
var popupCustom = searchWidget.on('select-result', function(evt){
//console.info(evt);
view.popup.open({
location: evt.result.feature.geometry, // location of the click on the view
title: "Service Availability:", // title displayed in the popup
content: "<p><b>{IN_COUNTRY}"
});
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
From your code you are mixing the popup template value with when to display it. And those are two different things.
First, you are not setting correctly the popup template of the layer. It should be a PopupTemplate.
It seems to me that in you code the layer definition should be something like this,
var Cyber_Areas = new FeatureLayer({
url: "*inserturl*",
popupTemplate: {
outFields: ["IN_COUNTRY"],
title: "Service Availability:",
content: "<p><b>{IN_COUNTRY}</b></p>"
}
});
Now if you don't want the default behavior of the popup (left click on a feature), you cant disable it like this,
view.popup.autoOpenEnabled = false; // <- disable view popup auto open
And then you can open it wherever you want like this,
view.popup.open({ // <- open popup
location: evt.result.feature.geometry, // <- use map point of the event result
fetchFeatures: true // <- fetch the selected features (if any)
});
You have to understand that the fields you use in the content of the popup template are related to the layer. That is why i set in the popup of the view to fetch the results.

How to draw a polyline using the mouse and leaflet.js

I would like to draw a polyline on a map with leaflet. The basic gesture that I would like to apply is:
User clicks and holds on the mouse button -> that defines the first marker. If the user holds the mouse button, and moves the mouse, a corresponding "rubber band" is displayed.
User releases the mouse button -> a second marker is added to the map and the 2 markers are linked by a line.
Starting from the second marker, the user can continue building a second line using the the same procedure as above.
The final result should be the set of coordinates/markers, linked by a polyline.
As Julien V and IvanSanchez said, you can implement some of the draw-like plugins
In example below:
You can see usage of Leaflet.draw plugin. Hope it helps :)
// center of the map
var center = [46.165164, 15.750443];
// Create the map
var map = L.map('map').setView(center,15);
// Set up the OSM layer
L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Data © OpenStreetMap',
maxZoom: 18
}).addTo(map);
// Initialise the FeatureGroup to store editable layers
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);
var options = {
position: 'topleft',
draw: {
polygon: {
allowIntersection: false, // Restricts shapes to simple polygons
drawError: {
color: '#e1e100', // Color the shape will turn when intersects
message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
},
shapeOptions: {
color: '#97009c'
}
},
polyline: {
shapeOptions: {
color: '#f357a1',
weight: 10
}
},
// disable toolbar item by setting it to false
polyline: true,
circle: true, // Turns off this drawing tool
polygon: true,
marker: true,
rectangle: true,
},
edit: {
featureGroup: editableLayers, //REQUIRED!!
remove: true
}
};
// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);
map.on('draw:created', function(e) {
var type = e.layerType,
layer = e.layer;
if (type === 'polyline') {
layer.bindPopup('A polyline!');
} else if ( type === 'polygon') {
layer.bindPopup('A polygon!');
} else if (type === 'marker')
{layer.bindPopup('marker!');}
else if (type === 'circle')
{layer.bindPopup('A circle!');}
else if (type === 'rectangle')
{layer.bindPopup('A rectangle!');}
editableLayers.addLayer(layer);
});
html, body, #map { margin: 0; height: 100%; width: 100%; }
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.2.rc.2/leaflet.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.2.rc.2/leaflet.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.css" rel="stylesheet" />
<meta charset="utf-8">
<title>TEST</title>
</head>
<body>
<div id='map'></div>
</body>
</html>

Leaflet JS + Leaflet.Deflate - Changing default marker icon to custom icon

In my previous post 'Leaflet JS - changing esri shape into marker on certain zoom level
' I was able to resolve an issue which i had with the leaflet JS library and changing the polygon shapes to markers icons when hitting a certain zoom level.
I was advised by 'Ivan Sanchez' to use the 'Leaflet.Deflate' plugin and this works like a charm, so now the various shapes are being transformed into markers after a certain zoomlevel, however now I'm struggling to change the default leaflet marker icon to a custom marker icon, so my question now is:
Is it possible to change the default marker icon to a custom marker icon while using the 'Leaflet.ShapeFile' and 'Leaflet.Deflate' plugin and what would be the best approach to do this?
I wanted to make a JSFiddle, but I don't JSFiddle allows me to attach the zip file contains the shapefiles, so I will post the code I have got so far below here, thanks for your help, advise and support:
<!doctype html>
<html lang="en">
<head>
<meta charset='utf-8' />
<title>v4</title>
<link rel="stylesheet" type="text/css" href="lib/leaflet/leaflet.css" />
<!--[if lte IE 8]> <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.ie.css" /> <![endif]-->
<link rel="stylesheet" type="text/css" href="lib/leaflet/L.Control.Sidebar.css" />
<style>
html { height: 100% }
body { height: 100%; margin: 0; padding: 0; }
#map { height: 100% }
</style>
</head>
<body>
<div id="map"></div>
<script src="lib/jquery/jquery-3.1.1.min.js"></script>
<script src="lib/leaflet/leaflet.js"></script>
<script src="lib/leaflet/catiline.js"></script>
<script src="lib/leaflet/leaflet.shpfile.js"></script>
<script src="lib/leaflet/shp.js"></script>
<script src="lib/leaflet/L.Control.Sidebar.js"></script>
<script src="lib/leaflet/L.Deflate.js"></script>
<script>
// init map
var m = L.map('map').setView([52.472833, 1.749609], 15);
// clicking on the map will hide the sidebar plugin.
m.on('click', function () {
sidebar.hide();
});
// init Deflate plugin
L.Deflate({ minSize: 10 }).addTo(m);
// Init side bar control
var sidebar = L.control.sidebar('sidebar', { closeButton: true, position: 'right' });
m.addControl(sidebar);
// Init esri shape file via leaflet.shapefile, shp.js plugin
var businessProperties = new L.Shapefile('data/businessshapes.zip', { style: propertyStyle, onEachFeature: propertyOnEachFeature }).addTo(m);
// create on-click Feature
function propertyOnEachFeature(feature, layer) {
layer.on( {
mouseover: highlightFeature,
mouseout: resetHighlight,
click: function populate() {
sidebar.toggle();
document.getElementById('pinfoHeader').innerHTML = "<h2>" + feature.properties.Building + " - Detailed Information</h2><br />";
document.getElementById('pTitle').innerHTML = "Name: " + feature.properties.Building
document.getElementById('pDetails').innerHTML = "SHAPE_Leng: " + feature.properties.SHAPE_Leng + "<br/ >SHAPE_Area: " + feature.properties.SHAPE_Area
}, highlightFeature, zoomToFeature
});
}
// style the properties style
function propertyStyle(feature) {
return {
fillColor: getPropertyColor(feature.properties.BusType),
weight: 2,
opacity: 1,
color: 'white',
dashArray: 3,
fillOpacity: 0.7
}
}
// set color per property according to the data table of the Esri Shape file.
function getPropertyColor(propStatus) {
if (propStatus == 'TypeA') {
return 'red';
} else if (propStatus == 'TypeB') {
return 'green';
} else {
return 'yellow';
}
}
// set the highlighted color for polygon
function highlightFeature(e) {
var layer = e.target;
layer.setStyle( {
weight: 2,
color: 'black',
fillColor: 'white',
fillOpacity: 0.2
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
}
// reset the highlighted color for polygon after mouse leave polygon
function resetHighlight(e) {
businessProperties.resetStyle(e.target);
}
//Extend the Default marker class to overwrite the leaflet.deflate marker icon???
var TestIcon = L.Icon.Default.extend({
options: {
iconUrl: 'assets/images/markers/business.png'
}
});
var testIcon = new TestIcon();
businessProperties.addTo(m);
// Init base maps for switch
var grayscale = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', { id: 'MapID', attribution: 'Map maintained by Demo LTD, — Map data © OpenStreetMap,' }).addTo(m);
var streets = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { id: 'MapID', attribution: 'Map maintained by Demo LTD, — Map data © OpenStreetMap,' });
var baseMaps = {
"Streets": streets,
"Grayscale": grayscale
};
// Init overlay map switch
var overlayMaps = {
"Bussines Properties": businessProperties
};
// Add switches to map control
L.control.layers(baseMaps, overlayMaps).addTo(m);
</script>
</body>
</html>
Is it possible to change the default marker icon to a custom marker icon while using the 'Leaflet.Deflate' plugin?
The answer is: No.
The current code for Leaflet.Deflate uses a default marker and a default marker only, see https://github.com/oliverroick/Leaflet.Deflate/blob/991f51ca82e7bb14a17c8d769b4c378c4ebaf700/src/L.Deflate.js#L42
You could hack your way around it, but I would rather recommend filing a feature request in the Leaflet.Deflate repo. It should be possible to modify the Leaflet.Deflate repo to allow line/polygon features to have some extra properties to be used as marker options.

custom heatmap leaflet plugin

in index.html I woluld like to add two Heatmaps users can see by checkbox in menu top right corner.
menu show other stuff by code like this
layerControl.addOverlay(geojson, "H2OpenMap");
in this portion of the page (line 383 to line 397)
$.getJSON('api.php', {'wells': '1'}, function(remoteData){
var geojson = L.geoJson(remoteData, {
pointToLayer: function (feature, latlng) {
var icon = chooseIcon(feature['properties']);
var marker = L.marker(latlng, {icon: new h2icon( {iconUrl: icon} )} );
var markerText = buildPopup(feature, true, latlng);
marker.bindPopup(markerText);
return marker;
}
}).addTo(map);
layerControl.addOverlay(geojson, "H2OpenMap");
map.fitBounds(geojson.getBounds(), {'padding': [10,10]});
});
First heat should use data from the same code before, selected by
if(feature['drinking_water'] == 'yes' ) {...
}
Second heat should use data from the same code before, selected by
if(feature['drinking_water'] == 'no' ) {...
}
The goal is to have two heat maps, one for clean water resources the other for not clean water resources, both can be selected by ratio button.
I've find this code looks good but I'm not able to give him data to use to create heatmap.....
//--------------------https://www.patrick-wied.at/static/heatmapjs/plugin-leaflet-layer.html-----------//
$.getJSON('api.php', {'wells': '1'}, function(remoteData){
var geojson = L.geoJson(remoteData, {
pointToLayer: function (feature, latlng) {
var heatData = L.marker(latlng);
console.log(heatData);
//var heatData = L.marker([{lat: new latlng(lat), lng: new latlng(lng)}]);
}})});
/*var testData = {
max: 8,
data: [{lat: 24.6408, lng:46.7728, count: 3},{lat: 50.75, lng:-1.55, count: 1}, ...]
};*/
var cleanWater = heatData;// mettere in un array solo la posizione degli elementi che rispettano la seguente condizione: feature['drinking_water'] == 'yes'
var cfg = {
// radius should be small ONLY if scaleRadius is true (or small radius is intended)
// if scaleRadius is false it will be the constant radius used in pixels
"radius": 2,
"maxOpacity": .8,
// scales the radius based on map zoom
"scaleRadius": true,
// if set to false the heatmap uses the global maximum for colorization
// if activated: uses the data maximum within the current map boundaries
// (there will always be a red spot with useLocalExtremas true)
"useLocalExtrema": true,
// which field name in your data represents the latitude - default "lat"
latField: 'lat',
// which field name in your data represents the longitude - default "lng"
lngField: 'lng',
// which field name in your data represents the data value - default "value"
valueField: 'count'
};
var heatmapLayer = new HeatmapOverlay(cfg);
var map = new L.Map('map-canvas', {
center: new L.LatLng(25.6586, -80.3568),
zoom: 4,
layers: [baseLayer, heatmapLayer]
});
heatmapLayer.setData(cleanWater);
//------------------------//--------------------//--------------------//--------------------//--------------------*/
in the root project it's following file with complete code:
https://github.com/H2OpenMap/map/blob/master/index_heat_test.html
Simplifying your problem I try to suggest you this example ...
http://bl.ocks.org/d3noob/raw/8973028/
This a simple code that implements a Leaflet heat map.
If you see at the source code ...
<!DOCTYPE html>
<html>
<head>
<title>Simple Leaflet Map with Heatmap </title>
<meta charset="utf-8" />
<link
rel="stylesheet"
href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css"
/>
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<script
src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js">
</script>
<script
src="http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js">
</script>
<script src="2013-earthquake.js"></script>
<script>
var map = L.map('map').setView([-41.5546,174.146], 10);
mapLink =
'OpenStreetMap';
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© ' + mapLink + ' Contributors',
maxZoom: 18,
}).addTo(map);
var heat = L.heatLayer(quakePoints,{
radius: 20,
blur: 15,
maxZoom: 17,
}).addTo(map);
</script>
</body>
.... you'll find that the data is simulated with a coordinate array that you can see here ...
http://bl.ocks.org/d3noob/raw/8973028/2013-earthquake.js
I think that you've to convert your geojson data in this format and all will work!
Cesare