1、概述
官网:https://developers.arcgis.com/qt/
https://developers.arcgis.com/qt/v100/
官网:官网指导
官网:Add graphics to a map view
官网:Esri官方博客
官网(github):https://github.com/Esri
Arcgis runtime sdk for Qt 开发记录(系列文章)
Arcgis runtime sdk for Android 开发记录(系列文章)
Android Arcgis(系列文章)
ArcGIS for Android 100.3.0(系列文章)
Cockpit-GUI-Design
【文档】:Tutorials for ArcGIS Runtime API for Qt
【文档】:ArcGIS Maps SDK for Qt C++ samples
ArcGIS Best Practices
1.1 数据格式
ArcGIS Runtime不能直接加载shp数据,或者mxd地图文档。ArcGIS Runtime所能支持的数据格式,我们可以称之为Package,目前包括MPK,TPK,GPK以及APK四种格式。
- Map package(MPK) :包含地图文档(mxd)以及图层引用的数据,这样便于用户或组织在ArcGIS Online上进行分享。
- Tile package(TPK):包含地图文档的缓存数据,也就是切片后的数据,TPK一方面便于用户或组织在ArcGIS Online上分享数据,另一方面也为离线条件下访问数据提 供一种方案。
- Geoprocessing package(GPK):是将一个能够成功运行的地理处理模型创建成一个压缩文件,方便分享分析和地理处理的工作流程。
- Locator package(APK):是将包含一个定位器或复合定位器的工具打包成一个方便、便携的文件,便于用户或组织在ArcGIS Online上分享。
1.2 几个基本数据
浅谈ArcGIS移动开发中的基本变量:Graphic、Geometry、Feature、GraphicsOverlay、FeatureLayer、FeatureTable、Symbol
【Smart3S】Arcgis系列文章
MapView,有GraphicsOverlay,可译为图形覆盖(物),用于容纳要显示在MapView上的临时图形,如查询或分析的结果,高亮,变化的事物、绘制的图形等,GraphicsOverlay由Graphic图形组成,因此也可看做Graphic图形的列表,Graphic图形包含几何、属性和符号。GraphicsOverlay分为静态和动态两种渲染模式,可通过Renderer进行渲染。
Map,即ArcGISMap,包含制图数据图层以及其它能够定义地图信息的数据(例如basemaps底图、popups弹出窗口、renderer渲染器、labels标签等)。它可以在MapView中可视化,也可以单独使用来访问数据。ArcGISMap可以包含一个Basemap底图和一个或多个operational layers操作图层。
view中的GrahicsOverlay为临时存储,Map中的为持续存储。
1.3 瓦片数据源
GIS开发一:OpenLayers在线瓦片数据源汇总
在线卫星地图:http://www.gditu.net/
google源:
地图:http://gac-geo.googlecnapps.cn/maps/vt/lyrs=m&x={x}&y={y}&z={z}
卫星:https://gac-geo.googlecnapps.cn/maps/vt?lyrs=s,m&gl=CN&x={x}&y={y}&z={z}&src=app&scale=2&from=app
arcgis源:
// 街道图:
https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}
// 灰色图:
https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}
// 深蓝夜色:
https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}
// 其他,Esri World Image瓦片地址
https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}
https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}
//Esri Imagery/Satellite
https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}
//Esri Streets
https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}
//Esri Topo
https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}
//World Light Gray Base
https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}
2、创建地图
//online:
m_mapView = new MapGraphicsView(this);
m_map = new Map(Basemap::lightGrayCanvas(this), this);
m_mapView->setMap(m_map);
pMainLayout->addWidget(m_mapView);
setCentralWidget(pMainWidget);
m_mapView->setAttributionTextVisible(false);
//本地
m_mapView = new MapGraphicsView(this); //初始化mapview窗体
TileCache *titlecahe=new TileCache(("C:/Users/dujia/Desktop/aaa.tpk"),this); //加载本地apk
ArcGISTiledLayer *titleLayer=new ArcGISTiledLayer(titlecahe,this); //新建平铺图层
Basemap *baseMap=new Basemap(titleLayer); //底图-----------
m_map = new Map(baseMap, this); //加载底图
m_mapView->setMap(m_map); //将地图设置到map_view
//tpk
Mapload_Widgets::Mapload_Widgets(QApplication* application, QWidget* parent /*=nullptr*/):
QMainWindow(parent), form(new Ui::Form)
{
// Create the Widget view
m_mapView = new MapGraphicsView(this);
// 加载 Tile Pack 地图文件,路径为宏定义
const QString worldMapLocation = QString(WORLDMAPPATH);
const QString countryMapLocation = QString(COUNTRYMAPPATH);
TileCache* worldTileCache = new TileCache(worldMapLocation, this);
TileCache* countryTileCache = new TileCache(countryMapLocation, this);
ArcGISTiledLayer* worldTiledLayer = new ArcGISTiledLayer(worldTileCache, this);
ArcGISTiledLayer* countryTiledLayer = new ArcGISTiledLayer(countryTileCache, this);
// 设置附加图层透明度
countryTiledLayer->setOpacity(0.7F);
// 实例化地图,设置附加图层
Basemap* basemap = new Basemap(worldTiledLayer, this);
m_map = new Map(basemap, this);
m_map->operationalLayers()->append(countryTiledLayer);
// Set map to map view
m_mapView->setMap(m_map);
// set the mapView as the central widget
setCentralWidget(m_mapView);
// 隐藏界面下方的"Powered by Esri"
m_mapView->setAttributionTextVisible(false);
}
3、定位、旋转、缩放
void Arcgis_demo::addButtons(QVBoxLayout* layout)
{
// 定位
QPushButton* pButtonLocate = new QPushButton("locate");
connect(pButtonLocate, &QPushButton::clicked, this, [this](){
// 经纬度坐标,这里用了“天坛公园”的位置
Point pt(116.4104, 39.8818, SpatialReference::wgs84());
// 比例尺设置
double scale = 30000.0;
m_mapView->setViewpointCenter(pt, scale);
});
layout->addWidget(pButtonLocate);
// 旋转 30°
QPushButton* pButtonRotate = new QPushButton("rotate");
connect(pButtonRotate, &QPushButton::clicked, this, [this](){
double cur_rotation = m_mapView->currentViewpoint(ViewpointType::CenterAndScale).rotation();
cur_rotation += 30.0;
m_mapView->setViewpointRotation(cur_rotation);
});
layout->addWidget(pButtonRotate);
// 放大
QPushButton* pButtonZoomIn = new QPushButton("zoom in");
connect(pButtonZoomIn, &QPushButton::clicked, this, [this](){
double cur_scale = m_mapView->currentViewpoint(ViewpointType::CenterAndScale).targetScale();
cur_scale -= 10000.0;
m_mapView->setViewpointScale(cur_scale);
});
layout->addWidget(pButtonZoomIn);
// 缩小
QPushButton* pButtonZoomOut = new QPushButton("zoom out");
connect(pButtonZoomOut, &QPushButton::clicked, this, [this](){
double cur_scale = m_mapView->currentViewpoint(ViewpointType::CenterAndScale).targetScale();
cur_scale += 10000.0;
m_mapView->setViewpointScale(cur_scale);
});
layout->addWidget(pButtonZoomOut);
}
4、鼠标点坐标
void T3::onMouseClicked(QMouseEvent &event)
{
//单机地图时触发
Point point = m_mapView->screenToLocation(event.x(), event.y()); //本地坐标转地图坐标
qDebug() << "point::" <<point << ":::" << point.x()<<"::"<<point.y();
Geometry geometryWgs84 = GeometryEngine::project(point, SpatialReference::wgs84()); //坐标转化
qDebug() << "pointxxxxxx:::" << geometryWgs84;
}
5、设置地图中心点位置
m_mapView->setViewpointCenter(m_CenterPoint);
6、画线测距
官方文档:关于测量
arcgis for qt在地图上做测距(画线和显示距离,单位km)
(1)GeometryEngine
(2) LocationDistanceMeasurement(in scene view.)
QList <Point> m_List;
Point point = m_mapView->screenToLocation(event.x(), event.y()); //本地坐标转地图坐标
Point geometryWgs84 = GeometryEngine::project(point, SpatialReference::wgs84()); //地图坐标转经纬度
m_List.append(geometryWgs84);
if (m_List.size() >= 2)
{
const QList<Point> points = { m_List[0], m_List[1] };
const Polyline polyline = pointsToPolyline(points);
constexpr double maxSegmentLength = 1.0;
const LinearUnit unitOfMeasurement(LinearUnitId::Kilometers);
constexpr GeodeticCurveType curveType = GeodeticCurveType::Geodesic;
const Geometry pathGeometry = GeometryEngine::densifyGeodetic(polyline, maxSegmentLength, unitOfMeasurement, curveType);
m_pathGraphic->setGeometry(pathGeometry);
qDebug() << "aaaaa::" << QString::number(GeometryEngine::lengthGeodetic(pathGeometry, unitOfMeasurement, curveType), 'f', 2); //测距
}
计算周长:
Polyline polyline = new Polyline();
polyline.startPath(new Point(110,13));
polyline.lineTo(new Point(115,13));
polyline.lineTo(new Point(115,23));
double length = GeometryEngine.geodesicLength(polyline,SpatialReference.create(SpatialReference.WKID_WGS84),new LinearUnit(LinearUnit.Code.METER));
Point point1 = new Point(113,23);
Point point2 = new Point(113,24);
double distance = GeometryEngine.geodesicDistance(point3,point4, SpatialReference.create(SpatialReference.WKID_WGS84), new LinearUnit(LinearUnit.Code.KILOMETER));
7、距离和线上某点
c一下:距离 GeometryEngine.DistanceGeodetic
SpatialReference spatialReference = SpatialReference.Create(4326); // 设置坐标系为WGS 84
MapPoint point1 = new MapPoint(0, 0, spatialReference); // 第一个点的经纬度
MapPoint point2 = new MapPoint(0, 1, spatialReference); // 第二个点的经纬度
double distance = GeometryEngine.DistanceGeodetic(point1, point2);
Console.WriteLine("地理距离:" + distance + "米");
c一下: GeometryEngine.project
// 导入GeometryEngine类
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polyline;
// 创建起始点
Point startPoint = new Point(x1, y1);
// 创建线
Polyline polyline = new Polyline();
polyline.startPath(startPoint);
polyline.lineTo(x2, y2); // 添加线上的一个点
// 求线上某个距离的点
double distance = 100; // 距离,单位为米
Point resultPoint = GeometryEngine.project(startPoint, polyline, distance);
// 输出结果
System.out.println("线上距离起始点 " + distance + " 米的点坐标为 (" + resultPoint.getX() + ", " + resultPoint.getY() + ")");
Point pointAlong = GeometryEngine.Instance.CreatePointAlong(polyline, 200);
求测向线上一点:
根据起始点经纬度、距离、方位角计算目标点经纬度的方法
已知基点的经纬度,根据方位角和运动距离求另外一点的经纬度
计算经纬度、距离、方位角(好)
void calcLatAndlon(double basePointLongitude, double basePointLatitude, double azimuth, double distance)
{
// 地球半径 单位米(m)
double arc = 6371.393 * 1000;
// 终点的经度坐标
double longitude = basePointLongitude + distance * Math.sin(azimuth) / (arc * Math.cos(basePointLongitude) * 2 * Math.PI / 360);
// 终点的纬度坐标
double latitude = basePointLatitude + distance * Math.cos(azimuth) / (arc * 2 * Math.PI / 360);
}
总结:c++求距离方位
#include <math.h>
#include <iostream>
// PI
#define M_PI 3.14159265358979323846
// 地球半径
const double EARTH_RADIUS = 6371000;
// 角度转弧度
double A2R(double d)
{
return d * M_PI / 180.0;
}
// 弧度转角度
double R2A(double d)
{
return d / M_PI * 180.0;
}
// 获取两经纬度之间的距离(m)
double GetDistanceCpp(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = A2R(lat1);
double radLat2 = A2R(lat2);
double a = radLat1 - radLat2;
double b = A2R(lng1) - A2R(lng2);
double s = 2 * asin(sqrt(pow(sin(a/2),2) +cos(radLat1)*cos(radLat2)*pow(sin(b/2),2)));
s = s * EARTH_RADIUS;
return s;
}
// 获取两经纬度之间的方位角(°) 纬度 精度 纬度 经度
double GetYaw(double lat1, double lon1, double lat2, double lon2)
{
double result = 0.0;
int ilat1 = (int) (0.50 + lat1 * 360000.0);
int ilat2 = (int) (0.50 + lat2 * 360000.0);
int ilon1 = (int) (0.50 + lon1 * 360000.0);
int ilon2 = (int) (0.50 + lon2 * 360000.0);
lat1 = A2R(lat1);
lon1 = A2R(lon1);
lat2 = A2R(lat2);
lon2 = A2R(lon2);
if ((ilat1 == ilat2) && (ilon1 == ilon2)){return result;}
else if (ilon1 == ilon2){if (ilat1 > ilat2){result = 180.0;}}
else
{
double c = acos(sin(lat2) * sin(lat1) + cos(lat2)* cos(lat1) * cos((lon2 - lon1)));
double A = asin(cos(lat2) * sin((lon2 - lon1)) / sin(c));
result = R2A(A);
if ((ilat2 > ilat1) && (ilon2 > ilon1)){}
else if ((ilat2 < ilat1) && (ilon2 < ilon1)){result = 180.0 - result;}
else if ((ilat2 < ilat1) && (ilon2 > ilon1)){result = 180.0 - result;}
else if ((ilat2 > ilat1) && (ilon2 < ilon1)){result += 360.0;}
}
if(result<0){result +=360.0;}
if(result>360){result -=360.0;}
return result;
}
//经纬度转(墨卡托)米
QPointF LatLongToMeterXY(double lon, double lat)
{
// 地球的周长的一半 20037508.342789244 单位米
double circumferenceHalf = M_PI * 2 * 6378137 / 2.0;
double mx = lon * circumferenceHalf / 180;
double temp = log(tan((90 + lat) * (M_PI / 360.0))) / (M_PI / 180.0);
double my = circumferenceHalf * temp / 180;
return QPointF(mx,my);
}
//计算墨卡托方位角
double getMAzimuth(double lon1, double lat1, double lon2, double lat2)
{
QPointF geo1 = LatLongToMeterXY(lon1, lat1);
QPointF geo2 = LatLongToMeterXY(lon2, lat2);
double ratio = (geo2.y() - geo1.y())/(geo2.x() - geo1.x());
double yaw1 = atan(ratio);
return yaw1;
}
8、去除底部文字(powered by Esri)
m_mapView->setAttributionTextVisible(false);
9、画各种图形
官方例子:Create and edit geometries
ArcGis Qt跨平台开发【4】–绘图层(overlay)
ArcGis Qt跨平台开发【5】–绘制矩形和圆
android arcgis 绘制圆_Arcgis runtime for Android 100.5 (五) 地图上绘制点、线、面、文字、图片…
ArcGIS for Android 100.3.0(8):绘制点,线,面,圆,添加文本和图片
点:Point、SimpleMarkerSymbol、PictureMarkerSymbol
线:Polyline、SimpleLineSymbol、PointCollection
面:Polygon、SimpleFillSymbol、PictureFillSymbol
字:TextSymbol
官方代码:(Geometry)生成点、线、面
//生成点
const Point wgsPoint = Point(-121, 38, SpatialReference::wgs84());
const Point projectedPoint = Point(GeometryEngine::project(wgsPoint, SpatialReference::webMercator()));
MultipointBuilder* multiPointBuilder = new MultipointBuilder(SpatialReference(4326), this);
//生成多点
PointCollection* pc = new PointCollection(SpatialReference(4326), this);
pc->addPoint(-169, 34, 2);
pc->addPoint(-171, 32);
pc->addPoint(Point(-175, 50, SpatialReference(4326)));
multiPointBuilder->setPoints(pc);
Multipoint mPoint(multiPointBuilder->toGeometry());
//生成Polyline
PolylineBuilder* polylineBuilder = new PolylineBuilder(SpatialReference(4326), this);
polylineBuilder->addPoint(-160, 34); // x,y-coordinates
polylineBuilder->addPoint(-175, 40, 25); // x,y,z-coordinates
polylineBuilder->addPoint(Point(-182, 36, SpatialReference(4326))); // A Point object
Polyline pline(polylineBuilder->toGeometry());
// Create a polygon builder; add the points
PolygonBuilder* polygonBuilder = new PolygonBuilder(SpatialReference(4326), this);
polygonBuilder->addPoint(-181, 35);
polygonBuilder->addPoint(-179, 34, 2);
polygonBuilder->addPoint(Point(-179, 35, SpatialReference(4326)));
// Get the defined polygon from the polygon builder
Polygon poly(polygonBuilder->toGeometry());
官方代码:添加点线面图像
// Create a point
const Point dume_beach(-118.80657463861, 34.0005930608889, SpatialReference::wgs84());
// Create symbols for the point
SimpleLineSymbol* point_outline = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 3, this);
SimpleMarkerSymbol* point_symbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Circle, QColor("red"), 10, this);
point_symbol->setOutline(point_outline);
// Create a graphic to display the point with its symbology
Graphic* point_graphic = new Graphic(dume_beach, point_symbol, this);
// Add point graphic to the graphics overlay
overlay->graphics()->append(point_graphic);
// Create a line
PolylineBuilder* polyline_builder = new PolylineBuilder(SpatialReference::wgs84(), this);
polyline_builder->addPoint(-118.8215, 34.0140);
polyline_builder->addPoint(-118.8149, 34.0081);
polyline_builder->addPoint(-118.8089, 34.0017);
// Create a symbol for the line
SimpleLineSymbol* line_symbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor(Qt::blue), 3, this);
// Create a graphic to display the line with its symbology
Graphic* polyline_graphic = new Graphic(polyline_builder->toGeometry(), line_symbol, this);
// Add line graphic to the graphics overlay
overlay->graphics()->append(polyline_graphic);
// Create a list of points to make up the polygon
const QList<Point> points = {
Point(-118.8190, 34.0138),
Point(-118.8068, 34.0216),
Point(-118.7914, 34.0164),
Point(-118.7960, 34.0086),
Point(-118.8086, 34.0035),
};
// Create a polygon using the list of points above
PolygonBuilder* polygon_builder = new PolygonBuilder(SpatialReference::wgs84(), this);
polygon_builder->addPoints(points);
// Create symbols for the polygon
SimpleLineSymbol* polygon_line_symbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor(Qt::blue), 3, this);
SimpleFillSymbol* fill_symbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor(Qt::yellow), polygon_line_symbol, this);
// Create a graphic to display the polygon with its symbology
Graphic* polygon_graphic = new Graphic(polygon_builder->toGeometry(), fill_symbol, this);
// Add polygon graphic to the graphics overlay
overlay->graphics()->append(polygon_graphic);
通过SimpleMarkerSymbol创建点符号
通过PictureMarkerSymbol创建点符号
c一下生成的画线代码:(待验证)
#include <QCoreApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include "Esri/ArcGISRuntime/Map.h"
#include "Esri/ArcGISRuntime/MapQuickView.h"
#include "Esri/ArcGISRuntime/Geometry.h"
#include "Esri/ArcGISRuntime/SimpleLineSymbol.h"
#include "Esri/ArcGISRuntime/Graphic.h"
using namespace Esri::ArcGISRuntime;
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
// Create a map
Map* map = new Map(BasemapStyle::ArcGISStreets, 34.056295, -117.195800, 16);
// Create a map view
MapQuickView* mapView = new MapQuickView();
mapView->setMap(map);
// Create line geometry
Point startPoint(-117.195800, 34.056295, SpatialReference::wgs84());
Point endPoint(-117.185800, 34.046295, SpatialReference::wgs84());
PolylineBuilder polylineBuilder(SpatialReference::wgs84());
polylineBuilder.addPoint(startPoint);
polylineBuilder.addPoint(endPoint);
Polyline polyline = polylineBuilder.toPolyline();
// Create line symbol
SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, Qt::blue, 2.0f);
// Create graphic
Graphic* lineGraphic = new Graphic(polyline, lineSymbol);
// Add graphic to the map view
mapView->graphicsOverlays()->at(0)->graphics()->append(lineGraphic);
// Show the map view
mapView->show();
return app.exec();
}
function drawCircle(centerX, centerY, radius) {
var circle = new QGeoCircle(centerX, centerY, radius);
var polygonBuilder = new PolygonBuilder();
var polygon = polygonBuilder.fromCircle(circle, 360);
var graphic = new Graphic();
graphic.geometry = polygon;
graphicsOverlay.graphics.append(graphic);
}
10、航迹
arcgis飞行轨迹动画_ArcGIS轨迹回放
ArcGIS轨迹回放(简单版)
11、显示自定义图片
Graphic:使用PictureMarkerSymbol实例化Graphic,添加到GraphicsOverlay中
// 用于GeometryEngine::ellipseGeodesic方法的参数类,指定图片标记的位置
GeodesicEllipseParameters ellipseParams(Point(X, Y, SpatialReference::wgs84()), 1, 1);
PictureMarkerSymbol* pictureMarkerSymbol = new PictureMarkerSymbol(image, this);
graphic = new Graphic(GeometryEngine::ellipseGeodesic(ellipseParams),pictureMarkerSymbol, this);
overlay->graphics()->appendgraphic);
12、更改图片标记的方向和位置
//ArcGIS更改图片标记的方向和位置
//Graphic::setGeometry(),PictureMarkerSymbol::setAngle()
GeodesicEllipseParameters ellipseParams(Point(x, y, SpatialReference::wgs84()), 1, 1);
graphic->setGeometry(GeometryEngine::ellipseGeodesic(ellipseParams));
pictureMarkerSymbol->setAngle(degree);
13、渲染
ClassBreaksRenderer、HeatmapRenderer、SimpleRenderer、UniqueValueRenderer、UnsupportedRenderer
通过SimpleRenderer进行符号渲染(上)
//创建多个点形成图形添加在地图上,以便于渲染器能够装饰它
//这些点存在于WGS84坐标系中
Point oldFaithfullPoint = new Point(-110.828140, 44.460458, SpatialReferences.getWgs84());
Point cascadeGeyserPoint = new Point(-110.829004, 44.462438, SpatialReferences.getWgs84());
Point plumeGeyserPoint = new Point(-110.829381, 44.462735, SpatialReferences.getWgs84());
//使用最远的点创建一个外接矩形用来确定地图的可见区域
Envelope initialEnvelope = new Envelope(oldFaithfullPoint, plumeGeyserPoint);
// 从layout中获取MapView控件
mMapView = (MapView) findViewById(R.id.mapView);
//创建一个具有影像底图的地图,这将使地图具有一个墨卡托投影的空间参考
ArcGISMap map = new ArcGISMap(Basemap.createImageryWithLabels());
// 设置地图在MapView中被显示
mMapView.setMap(map);
///在地图视图上设置初始的外接矩形并加上一些填充,从而使所有的点都是可见的
//这个外接矩形使用上面的WGS84点,但是被Mapview重新投影到地图的空间参考中,因此它能够很好地使用
mMapView.setViewpointGeometryAsync(initialEnvelope, 100);
//创建一个新的GraphicsOverlay然后把它添加到MapView上
GraphicsOverlay graphicOverlay = new GraphicsOverlay();
mMapView.getGraphicsOverlays().add(graphicOverlay);
//在simple renderer中创建一个simple symbol用于渲染
SimpleMarkerSymbol symbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CROSS, Color.RED, 12); //size 12, style of cross
SimpleRenderer renderer = new SimpleRenderer(symbol);
//将渲染器应用到GraphicsOverlay(因此所有图形都将使用来自渲染器的相同符号)
graphicOverlay.setRenderer(renderer);
//从geyser位置的点上创建图形。注意:不需要在图形上设置符号,因为渲染器会处理它
//这些点在WGS84坐标系中,但是图形会被自动重新投影,所以它们可以在具有web mercator空间参考的地图中很好地使用
Graphic oldFaithfullGraphic = new Graphic(oldFaithfullPoint);
Graphic cascadeGeyserGraphic = new Graphic(cascadeGeyserPoint);
Graphic plumeGeyserGraphic = new Graphic(plumeGeyserPoint);
graphicOverlay.getGraphics().add(oldFaithfullGraphic);
graphicOverlay.getGraphics().add(cascadeGeyserGraphic);
graphicOverlay.getGraphics().add(plumeGeyserGraphic);
通过SimpleRenderer进行符号渲染(下)
private void addGraphicsOverlay(){
// 点要素
Point pointGeometry = new Point(40e5, 40e5, SpatialReferences.getWebMercator());
// 设置简单符号,红色
SimpleMarkerSymbol pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.DIAMOND, Color.RED, 10);
// 新建graphic
Graphic pointGraphic = new Graphic(pointGeometry);
// 创建一个点集合图层 GraphicsOverlay
GraphicsOverlay pointGraphicOverlay = new GraphicsOverlay();
// 创建一个简单渲染器
SimpleRenderer pointRenderer = new SimpleRenderer(pointSymbol);
pointGraphicOverlay.setRenderer(pointRenderer);
// 添加Graphic到GraphicsOverlay
pointGraphicOverlay.getGraphics().add(pointGraphic);
// 添加到 MapView 显示
mMapView.getGraphicsOverlays().add(pointGraphicOverlay);
// 线图形
PolylineBuilder lineGeometry = new PolylineBuilder(SpatialReferences.getWebMercator());
lineGeometry.addPoint(-10e5, 40e5);
lineGeometry.addPoint(20e5, 50e5);
// 蓝色实心线符号
SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 5);
// 创建折线图形对象
Graphic lineGraphic = new Graphic(lineGeometry.toGeometry());
// 为折线创建GraphicOverlay
GraphicsOverlay lineGraphicOverlay = new GraphicsOverlay();
// 创建simple renderer
SimpleRenderer lineRenderer = new SimpleRenderer(lineSymbol);
// 将renderer添加到GraphicOverlay
lineGraphicOverlay.setRenderer(lineRenderer);
// 将graphic添加到GraphicOverlay
lineGraphicOverlay.getGraphics().add(lineGraphic);
// 将GraphicsOverlay添加到MapView
mMapView.getGraphicsOverlays().add(lineGraphicOverlay);
//多边形图形
PolygonBuilder polygonGeometry = new PolygonBuilder(SpatialReferences.getWebMercator());
polygonGeometry.addPoint(-20e5, 20e5);
polygonGeometry.addPoint(20e5, 20e5);
polygonGeometry.addPoint(20e5, -20e5);
polygonGeometry.addPoint(-20e5, -20e5);
// 黄色实心多边形符号
SimpleFillSymbol polygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.YELLOW, null);
//为多边形创建Graphic
Graphic polygonGraphic = new Graphic(polygonGeometry.toGeometry());
//为多边形创建GraphicOverlay
GraphicsOverlay polygonGraphicOverlay = new GraphicsOverlay();
// 创建simple renderer
SimpleRenderer polygonRenderer = new SimpleRenderer(polygonSymbol);
// 将renderer添加到GraphicOverlay
polygonGraphicOverlay.setRenderer(polygonRenderer);
// 将graphic添加到GraphicOverlay
polygonGraphicOverlay.getGraphics().add(polygonGraphic);
// 将GraphicsOverlay添加到MapView
mMapView.getGraphicsOverlays().add(polygonGraphicOverlay);
}
14、删除
ArcGIS轨迹回放(简单版)
//清除
removeOverlay(); //移除图层本身
layer.clear(); //清除图层上的对象
//设置动画
marker.setAnimation(BMAP_ANIMATION_BOUNCE);
marker.setAnimation(BMAP_ANIMATION_DROP);
15、显示/隐藏
setLayerVisible();
16、坐标转化
Point point1 = new Point(113,23);
Point point2 =(Point)GeometryEngine.project(point1,SpatialReference.create(SpatialReference.WKID_WGS84), SpatialReference.create(SpatialReference.WKID_WGS84_WEB_MERCATOR));
public void onClick(View arg0)
{
//快速定位到线
Polyline polyline = new Polyline();
polyline.startPath(new Point(110, 23));
polyline.lineTo(new Point(115, 25));
//由于加载的地图是墨卡托坐标,这里需要转坐标
Polyline polyline2 = (Polyline) GeometryEngine.project(polyline,
SpatialReference.create(SpatialReference.WKID_WGS84),
SpatialReference.create(SpatialReference.WKID_WGS84_WEB_MERCATOR));
mapView.setExtent(polyline2);
}
private void initLayer()
{
graphicsLayer = new GraphicsLayer();
mapView.addLayer(graphicsLayer);
Polyline polyline = new Polyline();
polyline.startPath(new Point(110, 23));
polyline.lineTo(new Point(115, 25));
//由于加载的地图是墨卡托坐标,这里需要转坐标
Polyline polyline2 = (Polyline) GeometryEngine.project(polyline,
SpatialReference.create(SpatialReference.WKID_WGS84),
SpatialReference.create(SpatialReference.WKID_WGS84_WEB_MERCATOR));
graphicsLayer.addGraphic(new Graphic(polyline2, new SimpleLineSymbol(
Color.RED, 3, SimpleLineSymbol.STYLE.SOLID)));
}
17、汽泡显示
官方例子:show callout
#ifdef PCH_BUILD
#include "pch.hpp"
#endif // PCH_BUILD
#include "ShowCallout.h"
#include "Map.h"
#include "MapQuickView.h"
#include "CalloutData.h"
#include "MapTypes.h"
#include "MapViewTypes.h"
#include "SpatialReference.h"
#include "Point.h"
#include "Viewpoint.h"
#include <QImage>
using namespace Esri::ArcGISRuntime;
ShowCallout::ShowCallout(QQuickItem* parent):
QQuickItem(parent)
{
}
ShowCallout::~ShowCallout() = default;
void ShowCallout::init()
{
qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView");
qmlRegisterType<ShowCallout>("Esri.Samples", 1, 0, "ShowCalloutSample");
qmlRegisterUncreatableType<CalloutData>("Esri.Samples", 1, 0, "CalloutData", "CalloutData is an uncreatable type");
}
void ShowCallout::componentComplete()
{
QQuickItem::componentComplete();
// find QML MapView component
m_mapView = findChild<MapQuickView*>("mapView");
m_mapView->setWrapAroundMode(WrapAroundMode::Disabled);
// Create a map using the topographic basemap
m_map = new Map(BasemapStyle::ArcGISTopographic, this);
m_map->setInitialViewpoint(Viewpoint(Point(-1.2e7, 5e6, SpatialReference::webMercator()), 1e7));
// Set map to map view
m_mapView->setMap(m_map);
//! [initialize callout]
m_mapView->calloutData()->setVisible(false);
m_mapView->calloutData()->setTitle("Location");
QImage image(":/Samples/DisplayInformation/ShowCallout/RedShinyPin.png");
m_mapView->calloutData()->setImage(image);
//! [initialize callout]
// display callout on mouseClicked
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent){
if (m_mapView->calloutData()->isVisible())
m_mapView->calloutData()->setVisible(false);
else
{
// set callout position
Point mapPoint(m_mapView->screenToLocation(mouseEvent.position().x(), mouseEvent.position().y()));
m_mapView->calloutData()->setLocation(mapPoint);
// set detail as coordinates formatted to decimal numbers with precision 2
m_mapView->calloutData()->setDetail("x: " + QString::number(mapPoint.x(), 'f', 2) + " y: " + QString::number(mapPoint.y(), 'f', 2));
m_mapView->calloutData()->setVisible(true);
}
});
}
ArcGIS for Android 100.3.0(10):Callout的使用
整个MapView中只有一个callout
m_mapView->calloutData()->setVisible(false);
m_mapView->calloutData()->setTitle("Location");
QImage image(":/Samples/DisplayInformation/ShowCallout/RedShinyPin.png");
m_mapView->calloutData()->setImage(image);
private void initCallout() {
//获取一个气泡
callout = mapView.getCallout();
//设置最大的长宽
callout.setMaxWidth(1200);
callout.setMaxHeight(300);
TextView tv = new TextView(this);
tv.setText("这是一个气泡");
callout.setContent(tv);
CalloutStyle calloutStyle = new CalloutStyle();
//设置尖尖角的位置,尖尖显示在气泡的左下角,
calloutStyle.setAnchor(Callout.ANCHOR_POSITION_LOWER_LEFT_CORNER);
callout.setStyle(calloutStyle);
}
}
TextView tw = new TextView(this);'
tw.setText("hello world");
callout = map.getCallout();
callout.setStyle(R.xml.calloutstyle);
callout.setOffset(0, -15);
callout.show(location, tw);
18、popup
官方例子:popup
#ifdef PCH_BUILD
#include "pch.hpp"
#endif // PCH_BUILD
#include "ShowPopup.h"
#include "FeatureLayer.h"
#include "Map.h"
#include "MapQuickView.h"
#include "PopupManager.h"
#include "PopupAttachmentListModel.h"
#include "IdentifyLayerResult.h"
#include "Error.h"
#include "MapTypes.h"
#include "LayerListModel.h"
#include "Feature.h"
#include "PopupManager.h"
#include "PopupAttachmentManager.h"
#include "PopupAttributeListModel.h"
#include "PopupAttachmentListModel.h"
#include <QUuid>
using namespace Esri::ArcGISRuntime;
ShowPopup::ShowPopup(QObject* parent /* = nullptr */):
QObject(parent),
m_map(new Map(QUrl("https://runtime.maps.arcgis.com/home/webmap/viewer.html?webmap=e4c6eb667e6c43b896691f10cc2f1580"), this))
{
}
ShowPopup::~ShowPopup() = default;
void ShowPopup::init()
{
// Register the map view for QML
qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView");
qmlRegisterType<ShowPopup>("Esri.Samples", 1, 0, "ShowPopupSample");
// Required to use the PopupManager with a QML UI.
qmlRegisterUncreatableType<PopupManager>("Esri.Samples", 1, 0, "PopupManager", "PopupManager is uncreateable");
qmlRegisterUncreatableType<PopupAttachmentManager>("Esri.Samples", 1, 0, "PopupAttachmentManager", "PopupAttachmentManager is uncreateable");
qmlRegisterUncreatableType<PopupAttributeListModel>("Esri.Samples", 1, 0, "PopupAttributeListModel", "PopupAttributeListModel is uncreateable");
qmlRegisterUncreatableType<PopupAttachmentListModel>("Esri.Samples", 1, 0, "PopupAttachmentListModel", "PopupAttachmentListModel is uncreateable");
}
MapQuickView* ShowPopup::mapView() const
{
return m_mapView;
}
// Set the view (created in QML)
void ShowPopup::setMapView(MapQuickView* mapView)
{
if (!mapView || mapView == m_mapView)
return;
m_mapView = mapView;
m_mapView->setMap(m_map);
// once map is set, connect to MapQuickView mouse clicked signal
connect(m_mapView, &MapQuickView::mouseClicked, this, &ShowPopup::onMouseClicked);
// connect to MapQuickView::identifyLayerCompleted signal
connect(m_mapView, &MapQuickView::identifyLayerCompleted, this, &ShowPopup::onIdentifyLayerCompleted);
emit mapViewChanged();
}
void ShowPopup::onIdentifyLayerCompleted(const QUuid&, IdentifyLayerResult* rawIdentifyResult)
{
emit taskRunningChanged();
auto identifyResult = std::unique_ptr<IdentifyLayerResult>(rawIdentifyResult);
// Invalid identify result
if (!identifyResult)
return;
if (!identifyResult->error().isEmpty())
{
qDebug() << "Identify error occurred: " << identifyResult->error().message();
return;
}
m_featureLayer->clearSelection();
const auto elements = identifyResult->geoElements();
for (GeoElement* geoElement : elements)
{
Feature* feature = static_cast<Feature*>(geoElement);
m_featureLayer->selectFeature(feature);
}
if (!identifyResult->popups().isEmpty())
{
// clear the list of PopupManagers
m_popupManagers.clear();
const auto popups = identifyResult->popups();
for (Popup* popup : popups)
{
// create a popup manager
PopupManager* popupManager = new PopupManager{popup, this};
// append popup manager to list
m_popupManagers.append(popupManager);
// notify QML that m_popupManagers has changed and to display the popup(s).
emit popupManagersChanged();
}
}
}
void ShowPopup::onMouseClicked(QMouseEvent& mouseEvent)
{
if (m_map->loadStatus() != LoadStatus::Loaded)
return;
Layer* layer = m_map->operationalLayers()->at(0);
if (layer->layerType() == LayerType::FeatureLayer)
{
m_featureLayer = static_cast<FeatureLayer*>(layer);
}
constexpr double tolerance = 12;
constexpr bool returnPopupsOnly = false;
constexpr int maximumResults = 10;
m_taskWatcher = m_mapView->identifyLayer(m_featureLayer, mouseEvent.position().x(), mouseEvent.position().y(), tolerance, returnPopupsOnly, maximumResults);
if (!m_taskWatcher.isValid())
qWarning() << "Task not valid.";
emit taskRunningChanged();
}
bool ShowPopup::taskRunning() const
{
return !m_taskWatcher.isDone();
}
QQmlListProperty<PopupManager> ShowPopup::popupManagers()
{
return QQmlListProperty<PopupManager>(this, &m_popupManagers);
}
void ShowPopup::clearSelection() const
{
m_featureLayer->clearSelection();
}
18、文字
TextSymbol textSymbol = new TextSymbol(20,"我是文字" , Color.RED);
Graphic graphic = new Graphic(new Point(113,22), textSymbol );
graphicsLayer.addGraphic(graphic);
19、GPS定位
ArcGIS for Android 100.3.0(9):GPS定位
20、查询
21、离线服务
Web地图服务规范(WMS、WMTS、TMS)简析
离线地图二次开发-支持多种离线地图格式
离线地图完整演示实例
22、求两点的方位角
chatgpt给出的墨卡托投影下两点的方位角
#include <iostream>
#include <cmath>
// 结构体表示点的墨卡托坐标
struct MercatorPoint {
double x; // x 坐标
double y; // y 坐标
};
// 将墨卡托坐标转换为经纬度
void mercatorToLatLon(const MercatorPoint& point, double& lat, double& lon) {
lon = (point.x / 20037508.34) * 180.0;
lat = (point.y / 20037508.34) * 180.0;
lat = 180 / M_PI * (2 * atan(exp(lat * M_PI / 180.0)) - M_PI / 2);
}
// 将经纬度转换为弧度
void degreesToRadians(double& value) {
value = value * M_PI / 180.0;
}
// 计算两个点之间的角度
double calculateAngle(const MercatorPoint& point1, const MercatorPoint& point2) {
double lat1, lon1, lat2, lon2;
// 将墨卡托坐标转换为经纬度
mercatorToLatLon(point1, lat1, lon1);
mercatorToLatLon(point2, lat2, lon2);
// 将经纬度转换为弧度
degreesToRadians(lat1);
degreesToRadians(lon1);
degreesToRadians(lat2);
degreesToRadians(lon2);
// 计算两点之间的角度
double y = sin(lon2 - lon1) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon2 - lon1);
double angle = atan2(y, x);
// 将弧度转换为度数
angle = angle * 180.0 / M_PI;
return angle;
}
int main() {
MercatorPoint point1 = { /* 第一个点的墨卡托坐标 */ };
MercatorPoint point2 = { /* 第二个点的墨卡托坐标 */ };
double angle = calculateAngle(point1, point2);
std::cout << "两点之间的角度为:" << angle << " 度" << std::endl;
return 0;
}
23、单击确定选中的图形
官方文档:Identify graphics
官方代码:
void IdentifyGraphics::connectSignals()
{
// connect to the mouse clicked signal on the MapQuickView
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
// call identify on the map view
constexpr double tolerance = 5.0;
constexpr bool returnPopupsOnly = false;
constexpr int maximumResults = 1;
//这里只识别一个图层,识别多个图层的函数为identifyGraphicsOverlays()
m_mapView->identifyGraphicsOverlay(m_graphicsOverlay, mouseEvent.position().x(), mouseEvent.position().y(), tolerance, returnPopupsOnly, maximumResults);
});
// connect to the identifyLayerCompleted signal on the map view
connect(m_mapView, &MapQuickView::identifyGraphicsOverlayCompleted, this, [this](const QUuid&, IdentifyGraphicsOverlayResult* rawIdentifyResult)
{
// Delete rawIdentifyResult on leaving scope.
auto identifyResult = std::unique_ptr<IdentifyGraphicsOverlayResult>(rawIdentifyResult);
if (identifyResult)
{
m_identifiedGraphicsCount = identifyResult->graphics().size();
emit identifiedGraphicsCountChanged();
}
});
}
chatgpt代码(待验证):
// 创建一个图形
SimpleMarkerSymbol* markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Circle, QColor("red"), 10.0, this);
Point point(x, y, SpatialReference::wgs84());
Graphic* graphic = new Graphic(point, markerSymbol, this);
graphic->attributes()->insertAttribute("id", QVariant(id)); // 设置图形的ID
// 将图形添加到图形覆盖层中
graphicsOverlay->graphics()->append(graphic);
// 注册图形覆盖层的mouseClicked信号
connect(graphicsOverlay, &GraphicsOverlay::mouseClicked, this, [this](QMouseEvent& event) {
// 获取鼠标单击的位置
Point clickedPoint = mapView->screenToLocation(event.pos());
// 设置查询参数
IdentifyGraphicsOverlayParameters params;
params.setGeometry(clickedPoint);
params.setTolerance(10.0);
params.setReturnPopupsOnly(false);
// 执行查询操作
QList<IdentifyGraphicsOverlayResult> results = mapView->identifyGraphicsOverlay(graphicsOverlay, params);
// 如果有查询结果,则选择最上面的那个图形
if (!results.isEmpty()) {
const IdentifyGraphicsOverlayResult& topResult = results.first();
Graphic* topGraphic = topResult.graphic();
// 获取选中的图形的ID
QVariant id = topGraphic->attributes()->attributeValue("id");
deleteSelectedGraphic(id);
}
});
void deleteSelectedGraphic(const QVariant& id) {
// 通过ID查找图形
Graphic* graphic = nullptr;
for (Graphic* g : graphicsOverlay->graphics()) {
QVariant graphicId = g->attributes()->attributeValue("id");
if (graphicId == id) {
graphic = g;
break;
}
}
// 如果找到了对应的图形,则将其从图形覆盖层中移除
if (graphic) {
graphicsOverlay->graphics()->removeOne(graphic);
delete graphic;
}
}
24、编辑图形
官方示例:Create and edit geometries
使用Esri::ArcGISRuntime::GeometryEditor,只能在Esri::ArcGISRuntime 200.1之后的版本中使用。文章来源:https://www.toymoban.com/news/detail-707518.html
25、画圆
chatgpt给的代码:文章来源地址https://www.toymoban.com/news/detail-707518.html
#include <QApplication>
#include <QQuickView>
#include <QPointF>
#include <QQmlContext>
#include <QVariant>
#include "Esri/ArcGISRuntime/Map.h"
#include "Esri/ArcGISRuntime/MapQuickView.h"
#include "Esri/ArcGISRuntime/GeometryEngine.h"
#include "Esri/ArcGISRuntime/Graphic.h"
#include "Esri/ArcGISRuntime/SpatialReference.h"
#include "Esri/ArcGISRuntime/Point.h"
#include "Esri/ArcGISRuntime/SimpleMarkerSymbol.h"
#include "Esri/ArcGISRuntime/SimpleFillSymbol.h"
using namespace Esri::ArcGISRuntime;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 创建一个带有地图视图的QQuickView实例
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
// 创建一个Map实例
Map map(new Basemap(BasemapStyle::ArcGISTopographic, &map));
// 创建一个MapQuickView实例并设置地图
MapQuickView mapQuickView;
mapQuickView.setMap(map);
// 创建一个圆形的几何对象
Point centerPoint(-118.37, 34.46, SpatialReference::wgs84());
double radius = 1000; // 半径,单位是米
Geometry circleGeometry = GeometryEngine::buffer(centerPoint, radius);
// 创建一个圆形的渲染符号
SimpleFillSymbol fillSymbol(SimpleFillSymbolStyle::Solid, Qt::red, nullptr);
fillSymbol.setOutline(SimpleLineSymbol(SimpleLineSymbolStyle::Solid, Qt::black, 1.0));
// 创建一个圆形的图形对象
Graphic circleGraphic(circleGeometry, fillSymbol);
// 将图形对象添加到地图中
map.getGraphicsOverlayListModel()->append(circleGraphic);
// 设置MapQuickView实例作为QQuickView的根对象
view.rootContext()->setContextProperty("mapQuickView", &mapQuickView);
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}
到了这里,关于ArcGis地图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!