javascript - 无法作为交 key 系统在 map 上绘制位置

标签 javascript delphi google-maps-api-3 delphi-2010

我有一个简单的自定义浏览器,可以显示运行良好的谷歌地图。我想要做的是使其成为一个交 key 表单,在打开时显示个人的位置并将其绘制在 map 上。

这是一个证明这个概念的小测试程序。

如果我通过显示表单并将值添加到编辑框并运行 ButtonGotoLocation 过程来添加位置,则每次都会有效。

如果我将其设置为交 key 系统,即调用 HTMLWindow2.execScript(Format('GotoLatLng(%s,%s)',['34','-84.00']), 'JavaScript');

我什至尝试创建表单并显示它,然后从调用表单调用过程。结果相同;

这是一个奇怪的并发问题吗?这就是为什么我使用外部程序但无济于事。

unit uStreetMap;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OleCtrls, SHDocVw, StdCtrls, ExtCtrls, XPMan, ComCtrls,MSHTML;

type
  TfrmMain = class(TForm)
    WebBrowser1: TWebBrowser;
    LabelAddress: TLabel;
    PanelHeader: TPanel;
    ButtonGotoLocation: TButton;
    XPManifest1: TXPManifest;
    MemoAddress: TMemo;
    ButtonGotoAddress: TButton;
    LabelLatitude: TLabel;
    LabelLongitude: TLabel;
    Longitude: TEdit;
    Latitude: TEdit;
    ButtonClearMarkers: TButton;

    procedure FormCreate(Sender: TObject);
    procedure ButtonGotoAddressClick(Sender: TObject);
    procedure ButtonGotoLocationClick(Sender: TObject);
    procedure ButtonClearMarkersClick(Sender: TObject);

    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
    HTMLWindow2: IHTMLWindow2;
    function UTCToSystemTime(UTC: TDateTime): TDateTime;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

uses
   ActiveX, DateUtils;


{$R *.dfm}

const
HTMLStr: AnsiString =
'<html> '+
'<head> '+
'<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> '+
'<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.24&amp;libraries=geometry"></script> '+
'<script type="text/javascript"> '+
''+
''+
'  var geocoder; '+
'  var map;  '+
'  var markersArray = [];'+
''+
''+
'  function initialize() { '+
'    geocoder = new google.maps.Geocoder();'+
'    var latlng = new google.maps.LatLng(40.714776,-74.019213); '+
'    var myOptions = { '+
'      zoom: 13, '+
'      center: latlng, '+
'      mapTypeId: google.maps.MapTypeId.ROADMAP '+
'    }; '+
'    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); '+
'    map.set("streetViewControl", false);'+
'  } '+
''+
''+
'  function codeAddress(address) { '+
'    if (geocoder) {'+
'      geocoder.geocode( { address: address}, function(results, status) { '+
'        if (status == google.maps.GeocoderStatus.OK) {'+
'          map.setCenter(results[0].geometry.location);'+
'          PutMarker(results[0].geometry.location.lat(), results[0].geometry.location.lng(), results[0].geometry.location.lat()+","+results[0].geometry.location.lng());'+
'        } else {'+
'          alert("Geocode was not successful for the following reason: " + status);'+
'        }'+
'      });'+
'    }'+
'  }'+
''+
''+
'  function GotoLatLng(Lat, Lang) { '+
'   var latlng = new google.maps.LatLng(Lat,Lang);'+
'   map.setCenter(latlng);'+
'   PutMarker(Lat, Lang, Lat+","+Lang);'+
'  }'+
''+
''+
'function ClearMarkers() {  '+
'  if (markersArray) {        '+
'    for (i in markersArray) {  '+
'      markersArray[i].setMap(null); '+
'    } '+
'  } '+
'}  '+
''+
'  function PutMarker(Lat, Lang, Msg) { '+
'   var latlng = new google.maps.LatLng(Lat,Lang);'+
'   var marker = new google.maps.Marker({'+
'      position: latlng, '+
'      map: map,'+
'      title: Msg+" ("+Lat+","+Lang+")"'+
'  });'+
' markersArray.push(marker); '+
'  }'+
''+
''+
''+'</script> '+
'</head> '+
'<body onload="initialize()"> '+
'  <div id="map_canvas" style="width:100%; height:100%"></div> '+
'</body> '+
'</html> ';

这会导致异常,因为脚本错误“GotoLatLng”未定义

procedure TfrmMain.FormActivate(Sender: TObject);
begin
   HTMLWindow2.execScript(Format('GotoLatLng(%s,%s)',['34.00','-84.00']), 'JavaScript');
end;

构造函数

procedure TfrmMain.FormCreate(Sender: TObject);
var
  aStream     : TMemoryStream;
begin
   WebBrowser1.Navigate('about:blank');
    if Assigned(WebBrowser1.Document) then
    begin
      aStream := TMemoryStream.Create;
      try
         aStream.WriteBuffer(Pointer(HTMLStr)^, Length(HTMLStr));
         aStream.Seek(0, soFromBeginning);
         (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream));
      finally
         aStream.Free;
      end;
      HTMLWindow2 := (WebBrowser1.Document as IHTMLDocument2).parentWindow;

    end;
end;

使用此过程效果很好。我在文本框中输入纬度/经度,然后单击按钮,一切顺利。

procedure TfrmMain.ButtonGotoLocationClick(Sender: TObject);
begin
   HTMLWindow2.execScript(Format('GotoLatLng(%s,%s)',[Latitude.Text,Longitude.Text]), 'JavaScript');
end;

但是如果我尝试让表单在 map 上显示位置(作为 key ),我会收到错误。

procedure TfrmMain.ButtonClearMarkersClick(Sender: TObject);
begin
  HTMLWindow2.execScript('ClearMarkers()', 'JavaScript')
end;

procedure TfrmMain.ButtonGotoAddressClick(Sender: TObject);
var
   address    : string;
begin
   address := MemoAddress.Lines.Text;
   address := StringReplace(StringReplace(Trim(address), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
   HTMLWindow2.execScript(Format('codeAddress(%s)',[QuotedStr(address)]), 'JavaScript');
end;


end.

最佳答案

好的,这就是我所做的。我在表单上放置了一个 TTimer 来执行调用 GotoLatLng 的脚本。由于我找不到使用信号 WaitForSingleObject 的句柄,这是我能做的最好的事情。我把它设置为1700毫秒,看起来时间足够了。 我还将 Map 创建从单元构造函数移到了表单构造函数中。

一切都很好。

关于javascript - 无法作为交 key 系统在 map 上绘制位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41094913/

相关文章:

javascript - Firefox 中的 setTimeout 延迟

不同浏览器上的javascript排序歧义

delphi - 在Delphi中查找 "non-leak"内存使用问题的策略或工具?

delphi - PNGImage "Access violation"程序结束时出现错误

javascript - 如何使用 jquery 隐藏 google.visualization.table 中的列

javascript - 如何在 Angular 路由中正确使用 href?

delphi - 使用shellexecute时 "printto"的参数是什么?

jquery - 谷歌地图在隐藏的 div 中不显示

javascript - 绘制后单击按钮删除多边形

javascript - Windows 中 Firefox 的行结束行为不一致