树莓派实现地图定位
企业在发展过程中需要更精细化的管理,对人员、车辆等可移动物体的位置检测是精细化管理的重要环节。
Raspberry Pi 是创客广泛使用的开发板,仅一张信用卡的大小就能实现强劲的计算。 Raspberry Pi 4 目前可刷写的Android为 LinageOS,官方目前未提供对 Raspberry Pi 的支持,我们可从 https://konstakang.com/devices/rpi4/ 下载社区支持的镜像刷写 Android 系统,PinToo 可在这个系统环境中完美流畅运行。
我们在 Raspberry Pi 4 中运行地图定位的示例。地图定位示例使用 OpenStreetMap 开放地图作为地图基底,这个地图不需要申请 API可直接使用,显示的效果不逊于 Google 地图。
- PinToo 内置定位的控件,如需要实现实时定位的功能,需要在系统中授权 PinToo 使用地图定位的权限。
- 获取的地图定位信息可标注于地图中,可配合 Web 图层显示。
- 将地图定位的数据信息存储为数据集,数据集的定位信息经处理可实现路径绘制,图形绘制等高级的功能。
将PinToo 安装于 Android 车载终端或手机终端,使用范例可实现实时定位的功能。
- 关于 PinToo:https://www.isoface.cn/isoface/production/software/pintoo
- PinToo下载:点击此处下载
- PinToo产品说明:https://www.isoface.cn/isoface/doc/pintoo/main/
- PinToo 快速上手:https://www.isoface.cn/isoface/study/quick-start/2022-05-28-03-08-29/pintoo
- PinToo 无需安装,在线试用:https://www.isoface.cn/isoface/support/trial/pintoo
相关代码如下:
var
ZoomLevel:double;
prevPopUp:string;
Marker:TTMSFNCMapsMarker;
Procedure fxSuperButton1OnClick(Sender: TObject);
Begin
fxFNCOpenLayers1.AddMarker(25.208768, 121.653944,'<font color="red"><b>' + Self.GetMsgLang('car') + '</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/car.png').DataInteger := 0;
//fxFNCOpenLayers1.AddMarker(24.212871, 120.670919,'<font color="red"><b>我是小汽車</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/car.png').DataInteger := 1;
//fxFNCOpenLayers1.AddMarker(24.674813, 121.478387,'<font color="red"><b>我是皮卡車</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/car.png').DataInteger := 2;
fxFNCOpenLayers1.AddMarker(25.200206, 121.649742,'<font color="red"><b>' + Self.GetMsgLang('cust') + '</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/cust.png').DataInteger := 3;
fxFNCOpenLayers1.AddMarker(25.199620, 121.675498,'<font color="red"><b>' + Self.GetMsgLang('supply') + '</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/supply.png').DataInteger := 4;
//fxFNCOpenLayers1.AddMarker(24.202322, 120.711247,'<font color="red"><b>我是儀表</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/meter.png').DataInteger := 5;
fxFNCOpenLayers1.SetCenterCoordinate(25.199806, 121.649742);
ZoomLevel := 14;
fxFNCOpenLayers1.SetZoomLevel(ZoomLevel);
End;
Procedure fxSuperButton2OnClick(Sender: TObject);
var
s:string;
Begin
if prevPopUp <> '' then
fxFNCOpenLayers1.ClosePopup(prevPopUp);
s :='<font color="red"><b>' + Self.GetMsgLang('rocket') + '</b></font><br>'
+ '<iframe width="240" height="240" src="https://isoface.net/isoface/images/video/rocket_2.mp4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"></iframe>';
prevPopUp := fxFNCOpenLayers1.ShowPopup(25.042232, 121.559655,s,-80,50);
fxFNCOpenLayers1.SetCenterCoordinate(25.042232, 121.559655);
End;
Procedure fxSuperButton3OnClick(Sender: TObject);
Begin
fxFNCOpenLayers1.CloseAllPopups;
fxFNCOpenLayers1.ClearMarkers;
fxFNCOpenLayers1.Markers.Clear;
fxFNCOpenLayers1.Clear;
End;
procedure AddRecord(ADataSet:TfxRFDataSet;ALatitude,ALongitude:double);
begin
ADataSet.Append;
ADataSet.FieldByName('Latitude').AsFloat := ALatitude;
ADataSet.FieldByName('Longitude').AsFloat := ALongitude;
ADataSet.Post;
End;
Procedure fxSuperButton4OnClick(Sender: TObject);
var
cdsData:TfxRFDataSet;
Begin
cdsData:=TfxRFDataSet.Create(nil);
try
{ 添加字段 }
cdsData.FieldDefs.Add('Latitude',ftFMTBcd,4,false);
cdsData.FieldDefs.Add('Longitude',ftFMTBcd,4,false);
{ 建数据集, 不可缺少的一步 }
cdsData.CreateDataSet;
AddRecord(cdsData,25.043759, 121.494587);
AddRecord(cdsData,25.053090, 121.505574);
AddRecord(cdsData,25.064662, 121.506369);
AddRecord(cdsData,25.072282, 121.506712);
AddRecord(cdsData,25.089073, 121.497614);
AddRecord(cdsData,25.094980, 121.490576);
fxFNCOpenLayers1.LoadGPXDataSet(cdsData,true,true,3,Orangered,false,false,600);
fxFNCOpenLayers1.AddMarker(25.043759, 121.494587,'<font color="green"><b>' + Self.GetMsgLang('start') + '</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/location.png');
fxFNCOpenLayers1.AddMarker(25.094980, 121.490576,'<font color="red"><b>' + Self.GetMsgLang('stop') + '</b></font><br>','https://s1.imagehub.cc/images/2022/08/24/location.png');
fxFNCOpenLayers1.SetCenterCoordinate(25.043759, 121.494587);
ZoomLevel := 12.5;
fxFNCOpenLayers1.SetZoomLevel(ZoomLevel);
Finally
//Except {ErrorMsg / RaiseMsg(Const Error:String)}
cdsData.Free;
End;
End;
//回至初始定位位置
Procedure fxSuperButton5OnClick(Sender: TObject);
Begin
fxFNCOpenLayers1.SetCenterCoordinate(25.042232, 121.559655);
ZoomLevel := 14;
fxFNCOpenLayers1.SetZoomLevel(ZoomLevel);
fxFNCOpenLayers1.AddMarker(25.042232, 121.559655,'','https://s1.imagehub.cc/images/2022/08/24/location.png');
End;
Procedure fxSuperButton6OnClick(Sender: TObject);
Begin
fxFNCOpenLayers1.SetCenterCoordinate(25.042232, 121.559655);
ZoomLevel := 14;
fxFNCOpenLayers1.SetZoomLevel(ZoomLevel);
fxFNCGeocoding1.GetReverseGeocodingResultCoordinate(25.042232, 121.559655,'','',mlmDefault);
fxFNCOpenLayers1.AddMarker(25.042232, 121.559655,'','https://s1.imagehub.cc/images/2022/08/24/location.png');
End;
Procedure fxRunFrameAfterShow(Sender: TObject);
Begin
ZoomLevel := fxFNCOpenLayers1.Options.DefaultZoomLevel;
End;
Procedure fxAMap1OnLocationChangedCallbackEvent(Sender: TObject; ErrorCode: Integer; ErrorInfo: string; LocationDetail: string; LocationType: Integer; Longitude: Double; Latitude: Double; Altitude: Double; Accuracy: Single; Provider: string; Speed: Single; Bearing: Single; Satellites: Integer; Country: string; Province: string; City: string; CityCode: string; District: string; AdCode: string; Address: string; PoiName: string; LocationTime: string; isWifiAble: Boolean; isWifiAbleString: string; GPSStatus: Integer; GPSStatusString: string);
Begin
if Marker = nil Then
Marker := fxFNCOpenLayers1.AddMarker(Latitude,Longitude,Self.GetMsgLang('altitude') + floattostr(Altitude)+'m '+formatdatetime('c',now())+'</b>','https://s1.imagehub.cc/images/2022/08/24/location.png');
begin
Marker.Release;
Marker.Latitude := Latitude;
Marker.Longitude := Longitude;
Marker.Title := Self.GetMsgLang('altitude') +floattostr(Altitude)+'m '+formatdatetime('c',now())+'</b>';
End;
fxFNCGeocoding1.GetReverseGeocodingResultCoordinate(Latitude,Longitude,'','',mlmDefault);
End;
Procedure fxRunFrameAfterScriptRun(Sender: TObject);
Begin
fxAMap1.StartLocation;
End;
Procedure fxFNCGeocoding1OnGetReverseGeocodingResult(Sender: TObject; AResult: TTMSFNCGeocodingRequest);
Begin
if AResult.Items.Count > 0 then
LabelLocation.Text := AResult.Items[0].Address;
End;
Procedure fxSuperButton7OnClick(Sender: TObject);
Begin
ZoomLevel := ZoomLevel + 0.5;
fxFNCOpenLayers1.SetZoomLevel(ZoomLevel);
End;
Procedure fxSuperButton8OnClick(Sender: TObject);
Begin
ZoomLevel := ZoomLevel - 0.5;
fxFNCOpenLayers1.SetZoomLevel(ZoomLevel);
End;
Begin
End.