我有一个delphi VCL应用程序,它将Mapbox映射加载到Twebbrowser组件中。我正在使用地图作为输入来获取GPS坐标和街道地址。javascript使您可以单击地图上的标记,也可以将其拖到其他位置。我有一个JavaScript函数,可在标记位置执行反向地址解析并将地址保存到变量中。
function getAddress(err, data){
var center = data.features[0].center;
streetAddress = data.features[0].place_name;
myMarker.setPopupContent("Position: <br /> lat = " + center[0] + "<br /> long = " + center[1] + "<br /> Address: " + streetAddress);
}
function delphiLocate(){
geocoder.reverseQuery(myMarker.getLatLng(), getAddress);
gpsCoords = myMarker.getLatLng().toString();
}
此功能可以通过单击标记或通过我的Delphi程序来调用。我的delphi代码还可以从javascript中读取address变量。
procedure TfrmCreateSpot.getSpotPos;
var
doc: OleVariant;
begin
doc := WebBrowser1.document;
doc.parentwindow.execScript('delphiLocate()', 'JavaScript');
sGpsCoords := doc.parentwindow.gpsCoords;
sGpsCoords := copy(sGpsCoords, Pos('(', sGpsCoords) + 1);
delete(sGpsCoords, Pos(')', sGpsCoords), 1);
sStreetAddress := doc.parentwindow.streetAddress;
end;
此getSpotPos过程在单击按钮以确认位置时调用。问题是,地理位置定位器需要一段时间才能返回结果,并且到它返回时,我的程序已经记录了最后一个标记位置的信息。
如何确保我从当前标记位置获得地址?
可能的解决方案:
1)如果每次移动标记时都调用locate函数,则在用户单击确认按钮之前,地理定位应该已经完成。但是,这似乎是一个很棘手的解决方案,可能不可靠,而且它可能会使用比必要更多的地理位置请求(这对我来说不是问题,因为这只是一个学校项目,不会超过我的100000上限,但是id希望实施最佳解决方案。
2)在javaScript中创建一个返回结果时为true的标志,在我的Delphi代码中,我可以使用计时器检查该标志是否为true,然后请求结果。
这里是完整的HTML脚本
<title>Map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.mapbox.com/mapbox.js/v3.3.0/mapbox.js'></script>
<link href='https://api.mapbox.com/mapbox.js/v3.3.0/mapbox.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; width : 100%; }
#map {position : absolute; top:0; bottom:0; width: 100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
function mapClick(e){
if (!locked){
myMarker.setLatLng(e.latlng);
}
}
function locate(e) {
geocoder.reverseQuery(e.latlng, getAddress);
gpsCoords = e.latlng.toString();
}
function getAddress(err, data){
var center = data.features[0].center;
streetAddress = data.features[0].place_name;
myMarker.setPopupContent("Position: <br /> lat = " + center[0] + "<br /> long = " + center[1] + "<br /> Address: " + streetAddress);
}
function centerMarker(e){
if (!locked){
var coords = e.feature.geometry.coordinates;
myMarker.setLatLng([coords[1],coords[0]]);// lat lng are swapped
}
}
function delphiLocate(){
geocoder.reverseQuery(myMarker.getLatLng(), getAddress);
gpsCoords = myMarker.getLatLng().toString();
}
var locked = false;
function toggleLock(){
if (!locked) {
myMarker.setIcon(redIcon);
myMarker.dragging.disable();
locked = true;
} else {
myMarker.setIcon(blueIcon);
myMarker.dragging.enable();
locked = false;
}
}
L.mapbox.accessToken = 'pk.eyJ1IjoiZ3JlZW5vbGl2ZSIsImEiOiJjazk4N3hpcngwMDU0M2VvMGhydGw2Z2YxIn0.wvwQzgwsaujmkNOX7Bs47A';
var map = L.mapbox.map('map')
.setView([-30.487,23.181], 6)
.addLayer(L.mapbox.styleLayer('mapbox://styles/greenolive/ck9fi6dbk3hag1itg5aem2ypi'));
var geocoderControl = L.mapbox.geocoderControl('mapbox.places',{autocomplete : true}).addTo(map);
var geocoder = L.mapbox.geocoder('mapbox.places');
var blueIcon = L.icon({
iconUrl: 'blueMarker.png',
iconSize: [40, 40], // size of the icon
iconAnchor: [20, 40], // point of the icon which will correspond to marker's location
popupAnchor: [0, -40] // point from which the popup should open relative to the iconAnchor
});
var redIcon = L.icon({
iconUrl: 'redMarker.png',
iconSize: [40, 40], // size of the icon
iconAnchor: [20, 40], // point of the icon which will correspond to marker's location
popupAnchor: [0, -40] // point from which the popup should open relative to the iconAnchor
});
var myMarker = L.marker(map.getCenter(), { draggable : true, icon : blueIcon}).addTo(map).bindPopup("Position: <br /> lat = " + map.getCenter().lat + "<br /> long = " + map.getCenter().lng+ "<br /> Address: ");
var gpsCoords;
var streetAddress;
map.on('click',mapClick);
myMarker.on('click', locate);
geocoderControl.on('select', centerMarker);
</script>
</body>
</html>
似乎您在此处设置变量gpsCoords
:
function delphiLocate(){
geocoder.reverseQuery(myMarker.getLatLng(), getAddress);
gpsCoords = myMarker.getLatLng().toString();
}
调用delphiLocate
函数后将在Delphi脚本中进行访问。因此,应更新JS中的gpsCoords
变量。但是,在您的Delphi脚本中,您仍然需要在调用doc
之前访问已加载的delphiLocate
对象。该对象仍应具有旧的gpsCoords
。
您可以在调用doc
之后尝试重新加载delphiLocate
对象吗?
doc := WebBrowser1.document;
doc.parentwindow.execScript('delphiLocate()', 'JavaScript');
doc := WebBrowser1.document;
sGpsCoords := doc.parentwindow.gpsCoords;