使用地理定位 [Onclick] 更新 Geojson 文件
Update Geojson file using Geolocation [Onclick]
我有一个本地 .json 文件,每个要素的坐标为 lat/long,还有一个空列 Distance(随机输入 999)。
总体目标是在传单地图中显示标记并使用按钮根据 geolcoation 对其进行过滤。
我正在尝试创建一个按钮,它能够:
获取我的当前位置
计算我的 json 文件中每个特征的距离(for 循环)
[阻塞点]更新列距离/或创建新列
根据距离过滤 json 文件(例如,显示距离小于 100 公里的标记)
我从中得到灵感example
但是遇到了 "callback hell" 问题。
我现在正处于第 3 步:我设法计算了距离。但不能在函数外工作。
这是我正在使用的代码,阻塞在 For 循环中:距离列未更新
var allmarkers = L.markerClusterGroup();
var markersdist100 = L.markerClusterGroup();
// Load json file
var promise = $.getJSON("./data/FILE.geojson");
promise.then(function(data) {
// Update distance in json data
// Geolocation part to get current position
var userPositionPromise = new Promise(function(resolve, reject) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(data1) {
resolve(data1);
}, function(error) {
reject(error);
});
} else {
reject({
error: 'browser doesn\'t support geolocation'
});
};
});
userPositionPromise.then(function(dataa) {
lat = dataa.coords.latitude;
lng = dataa.coords.longitude;
console.log(lng); // check ok : lng of current location
console.log(data.features.length); //check ok : json length for iteration
// For loop to calculate the new distance
for (var i = 0; i < data.features.length; i++) {
data.features[i].properties.distance = getDistanceFromLatLonInKm(lat, lng, data.features[i].geometry.coordinates[0], data.features[i].geometry.coordinates[1]);
console.log(data.features[i].properties.distance); //check ok : showing the right distance
}
})
console.log(data.features[0].properties.distance); //check BUG : showing initial distance [999]
//all data
var all = L.geoJson(data, {
pointToLayer: style_markers,
});
// data filtered by distance, see the function [filter_distance]
var distance100 = L.geoJson(data, {
pointToLayer: style_markers,
filter: filter_distance
});
// Filter distance on button click
$("#distance100").click(function() {
markersdist100.addLayer(distance100);
allmarkers.addLayer(all);
map.addLayer(markersdist100);
map.removeLayer(allmarkers);
});
});
// FUNCTIONS
function filter_distance(feature, other) {
return feature.properties.distance < 100;
};
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
};
function deg2rad(deg) {
return deg * (Math.PI / 180)
};
关于如何构建我的代码以使用更新的距离列访问数据,您有什么建议吗
谢谢
我找到了解决方案!
我只需要将 var distance100 放在 For 循环之后
使用这些功能:单击按钮,您可以根据当前位置过滤传单地图中的标记(通过更新 json 文件中的距离)
这里解决了很多情况:read/access 并更新 Geojson 本地文件,点击过滤 Leaflet 标记,在另一个函数中使用地理定位坐标,计算距离 ...
更新后的代码如下(加载地图和控件未涵盖):
var allmarkers = L.markerClusterGroup(); //markercluster plugin using leaflet
var markersdist100 = L.markerClusterGroup();
// Load json file
var promise = $.getJSON("./data/FILE.geojson");
promise.then(function(data) {
// Update distance in json data
// Geolocation part to get current position
var userPositionPromise = new Promise(function(resolve, reject) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(data1) {
resolve(data1);
}, function(error) {
reject(error);
});
} else {
reject({
error: 'browser doesn\'t support geolocation'
});
};
});
userPositionPromise.then(function(dataa) {
lat = dataa.coords.latitude;
lng = dataa.coords.longitude;
console.log(lng); // check ok : lng of current location
console.log(data.features.length); //check ok : json length for iteration
// For loop to calculate the new distance
for (var i = 0; i < data.features.length; i++) {
data.features[i].properties.distance = getDistanceFromLatLonInKm(lat, lng, data.features[i].geometry.coordinates[0], data.features[i].geometry.coordinates[1]);
console.log(data.features[i].properties.distance); //check ok : showing the right distance
};
// data filtered by distance, see the function [filter_distance]
var distance100 = L.geoJson(data, {
pointToLayer: style_markers,
filter: filter_distance
});
// Filter distance on button click
$("#distance100").click(function() {
markersdist100.addLayer(distance100);
allmarkers.addLayer(all);
map.addLayer(markersdist100);
map.removeLayer(allmarkers);
});
});
//all data
var all = L.geoJson(data, {
pointToLayer: style_markers,
});
});
// FUNCTIONS
function filter_distance(feature, other) {
return feature.properties.distance < 100;
};
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
};
function deg2rad(deg) {
return deg * (Math.PI / 180)
};
我的地图截图
希望这可以帮助其他人在他们的用例中
欢迎优化代码分享给我们
我有一个本地 .json 文件,每个要素的坐标为 lat/long,还有一个空列 Distance(随机输入 999)。
总体目标是在传单地图中显示标记并使用按钮根据 geolcoation 对其进行过滤。
我正在尝试创建一个按钮,它能够:
获取我的当前位置
计算我的 json 文件中每个特征的距离(for 循环)
[阻塞点]更新列距离/或创建新列
根据距离过滤 json 文件(例如,显示距离小于 100 公里的标记)
我从中得到灵感example 但是遇到了 "callback hell" 问题。 我现在正处于第 3 步:我设法计算了距离。但不能在函数外工作。
这是我正在使用的代码,阻塞在 For 循环中:距离列未更新
var allmarkers = L.markerClusterGroup();
var markersdist100 = L.markerClusterGroup();
// Load json file
var promise = $.getJSON("./data/FILE.geojson");
promise.then(function(data) {
// Update distance in json data
// Geolocation part to get current position
var userPositionPromise = new Promise(function(resolve, reject) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(data1) {
resolve(data1);
}, function(error) {
reject(error);
});
} else {
reject({
error: 'browser doesn\'t support geolocation'
});
};
});
userPositionPromise.then(function(dataa) {
lat = dataa.coords.latitude;
lng = dataa.coords.longitude;
console.log(lng); // check ok : lng of current location
console.log(data.features.length); //check ok : json length for iteration
// For loop to calculate the new distance
for (var i = 0; i < data.features.length; i++) {
data.features[i].properties.distance = getDistanceFromLatLonInKm(lat, lng, data.features[i].geometry.coordinates[0], data.features[i].geometry.coordinates[1]);
console.log(data.features[i].properties.distance); //check ok : showing the right distance
}
})
console.log(data.features[0].properties.distance); //check BUG : showing initial distance [999]
//all data
var all = L.geoJson(data, {
pointToLayer: style_markers,
});
// data filtered by distance, see the function [filter_distance]
var distance100 = L.geoJson(data, {
pointToLayer: style_markers,
filter: filter_distance
});
// Filter distance on button click
$("#distance100").click(function() {
markersdist100.addLayer(distance100);
allmarkers.addLayer(all);
map.addLayer(markersdist100);
map.removeLayer(allmarkers);
});
});
// FUNCTIONS
function filter_distance(feature, other) {
return feature.properties.distance < 100;
};
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
};
function deg2rad(deg) {
return deg * (Math.PI / 180)
};
关于如何构建我的代码以使用更新的距离列访问数据,您有什么建议吗
谢谢
我找到了解决方案!
我只需要将 var distance100 放在 For 循环之后
使用这些功能:单击按钮,您可以根据当前位置过滤传单地图中的标记(通过更新 json 文件中的距离)
这里解决了很多情况:read/access 并更新 Geojson 本地文件,点击过滤 Leaflet 标记,在另一个函数中使用地理定位坐标,计算距离 ...
更新后的代码如下(加载地图和控件未涵盖):
var allmarkers = L.markerClusterGroup(); //markercluster plugin using leaflet
var markersdist100 = L.markerClusterGroup();
// Load json file
var promise = $.getJSON("./data/FILE.geojson");
promise.then(function(data) {
// Update distance in json data
// Geolocation part to get current position
var userPositionPromise = new Promise(function(resolve, reject) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(data1) {
resolve(data1);
}, function(error) {
reject(error);
});
} else {
reject({
error: 'browser doesn\'t support geolocation'
});
};
});
userPositionPromise.then(function(dataa) {
lat = dataa.coords.latitude;
lng = dataa.coords.longitude;
console.log(lng); // check ok : lng of current location
console.log(data.features.length); //check ok : json length for iteration
// For loop to calculate the new distance
for (var i = 0; i < data.features.length; i++) {
data.features[i].properties.distance = getDistanceFromLatLonInKm(lat, lng, data.features[i].geometry.coordinates[0], data.features[i].geometry.coordinates[1]);
console.log(data.features[i].properties.distance); //check ok : showing the right distance
};
// data filtered by distance, see the function [filter_distance]
var distance100 = L.geoJson(data, {
pointToLayer: style_markers,
filter: filter_distance
});
// Filter distance on button click
$("#distance100").click(function() {
markersdist100.addLayer(distance100);
allmarkers.addLayer(all);
map.addLayer(markersdist100);
map.removeLayer(allmarkers);
});
});
//all data
var all = L.geoJson(data, {
pointToLayer: style_markers,
});
});
// FUNCTIONS
function filter_distance(feature, other) {
return feature.properties.distance < 100;
};
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
};
function deg2rad(deg) {
return deg * (Math.PI / 180)
};
我的地图截图
希望这可以帮助其他人在他们的用例中
欢迎优化代码分享给我们