在ArcGIS里我们经常要高亮显示一些图形,比如GPS轨迹,查询、分析出来的地块图形等。在ArcGIS10.2.X版本里,一般我们都会新建FeatureLayer来放置这些图形,然后渲染显示;但是在Runtime100 里删除了这个类,取而代之的是一个新类——GraphicsOverlay作为绘制图层,并和地图内容分开来。其和MapView以及ArcGISMap的关系如下所示:
单独把绘制图层拿出来的一个好处就是,它将永远置于地图内容之上。在以前我们如果要在MapView里加载一个新的图层,必须先remove带有图形的FeatureLayer,加载这个图层之后再加载一次带有图形的FeatureLayer,否则我们这个FeatureLayer将会被新加载的图层所覆盖。现在这个问题就不复存在了。
那么我们来看下GraphicsOverlay的用法吧。
GraphicsOverlay加载
首先是实例化。GraphicsOverlay的实例化方法如下:
GraphicsOverlay graphicsOverlay_1=new GraphicsOverlay(); GraphicsOverlay graphicsOverlay_2=new GraphicsOverlay(GraphicsOverlay.RenderingMode.DYNAMIC);
GraphicsOverlay默认的构造模式一共有两种:DYNAMIC和STATIC,默认的是动态渲染模式DYNAMIC。
当为DYNAMIC模式时候,每当图形有变化时候GraphicsOverlay会立刻更新图形;而为STATIC模式时候,图形变化了不会马上更新,而是在进行地图的缩放、旋转和平移时候才更新图层,适合于绘制图层里含有大量图形时候使用,以防图形更新太慢影响体验。
使用方法也很简单,只需要GraphicsOverlay.getGraphics().add(Graphic graphic),然后加载到MapView里即可。举一个简单的例子,以下代码是点击屏幕后在对应地方高亮显示个红点:
mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) { @Override public boolean onSingleTapConfirmed(MotionEvent v) { android.graphics.Point screenPoint=new android.graphics.Point(Math.round(v.getX()), Math.round(v.getY())); Point clickPoint = mMapView.screenToLocation(screenPoint); GraphicsOverlay graphicsOverlay_1=new GraphicsOverlay(); SimpleMarkerSymbol pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.DIAMOND, Color.RED, 10); Graphic pointGraphic = new Graphic(clickPoint,pointSymbol); graphicsOverlay_1.getGraphics().add(pointGraphic); mMapView.getGraphicsOverlays().add(graphicsOverlay_1); return true; } });
效果图如下:
图上四个点就是我点击的四下屏幕。
符号Symbol使用
Symbol类是一个用来控制显示图形符号样式的类。
比如在上述的例子里,我用了SimpleMarkerSymbol类来设置我要高亮显示点的样式为菱形,红色,10px大小。
在Runtime100里对于Symbol类也进行了比较大的更改,多了一些参数,使得符号的样式更加丰富。下面我简单的介绍下各类符号。
点符号(MarkerSymbol)
点符号,顾名思义就是用来修饰Point的符号。包含三种类型,分别是PictureMarkerSymbol(图片点符号), SimpleMarkerSymbol(简单点符号)和 TextSymbol(文本符号)。
SimpleMarkerSymbol的构造方法为:
SimpleMarkerSymbol(SimpleMarkerSymbol.Style style, int color, float size)三个参数分别是点样式,颜色以及点的大小。默认的构造参数为(circle,Black,0.0)
样式包含:
构造以后,有两种方法方法来使用,一种是直接构造新的图形,加入GraphicsOverlay里;另一种是加入到GraphicsOverlay的渲染里:
GraphicsOverlay.getGraphics().add(new Graphic(Geometry, SimpleMarkerSymbol)); GraphicsOverlay.setRenderer(new SimpleRenderer(SimpleMarkerSymbol));
PictureMarkerSymbol的构造方法为:
PictureMarkerSymbol(BitmapDrawable drawable)
PictureMarkerSymbol(String url)
PictureMarkerSymbol(String url, RequestConfiguration requestConfiguration)
其实就是给图片点符号里增加一个图片用以显示点。
不过构造以后PictureMarkerSymbol的使用稍微麻烦,因为涉及到加载图片到符号里,所以需要一个异步监听操作:
final PictureMarkerSymbol campsiteSymbol = new PictureMarkerSymbol(bitmapDrawable); campsiteSymbol.loadAsync(); campsiteSymbol.addDoneLoadingListener(new Runnable() { @Override public void run() { } });
TextSymbol的构造函数为:
TextSymbol(float size, String text, int color, TextSymbol.HorizontalAlignment hAlign, TextSymbol.VerticalAlignment vAlign)
一共有五个参数,分别是文本字体大小,文本内容,文字颜色以及相对于符号重点水平和竖直的对齐方式。
文本符号的使用方法很简单,和简单点符号相同。
线符号(LineSymbol)
线符号是用来修饰线PolyLine的符号。只有一种类型,SimpleLineSymbol(简单线符号)。
SimpleLineSymbol的构造函数为:
SimpleLineSymbol(SimpleLineSymbol.Style style, int color, float width)
三个参数跟SimpleMarketSymbol相似,分别是样式,颜色,和线宽度。默认的构造参数是(Null,Black,0.0)
样式为:
使用方法和SimpleMarketSymbol也是相似的,有两种方法方法来使用,一种是直接构造新的图形,加入GraphicsOverlay里;另一种是加入到GraphicsOverlay的渲染里:
GraphicsOverlay.getGraphics().add(new Graphic(Geometry, SimpleLineSymbol)); GraphicsOverlay.setRender(new SimpleRenderer(SimpleLineSymbol));
面符号(FillSymbol)
面符号是用来修饰面Polygon的符号,一共有两种PictureFillSymbol(图片面符号), SimpleFillSymbol(简单面符号)。
SimpleFillSymbol的构造函数为:
SimpleFillSymbol(SimpleFillSymbol.Style style, int color, LineSymbol outline)一共有三个参数,分别是面样式,颜色,以及面的外边线样式。默认参数为(Null,Black,Null )
样式为:
使用方法和SimpleMarketSymbol也是相似的,有两种方法方法来使用,一种是直接构造新的图形,加入GraphicsOverlay里;另一种是加入到GraphicsOverlay的渲染里:
GraphicsOverlay.getGraphics().add(new Graphic(Geometry, SimpleFillSymbol)); GraphicsOverlay.setRender(new SimpleRenderer(SimpleFillSymbol));
PictureMarkerSymbol的构造方法为:
用法同PictureMarkerSymbol,就不用多累述了。
介绍完了符号,举个例子说明下吧。结合本系列的三章,空间数据离线查询做一个I查询的功能,显示对应的面。废话不多说,上代码:
mMapView = (MapView) findViewById(R.id.mapview); arcGISMap = new ArcGISMap(); mMapView.setMap(arcGISMap); mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) { @Override public boolean onSingleTapConfirmed(MotionEvent v) { android.graphics.Point screenPoint=new android.graphics.Point(Math.round(v.getX()), Math.round(v.getY())); final Point clickPoint = mMapView.screenToLocation(screenPoint); QueryParameters query = new QueryParameters(); query.setGeometry(clickPoint);// 设置空间几何对象 FeatureTable mTable = dataFeatureLayer.getFeatureTable();//得到查询属性表 final ListenableFuturefeatureQueryResult = mTable.queryFeaturesAsync(query); featureQueryResult.addDoneListener(new Runnable() { @Override public void run() { try { FeatureQueryResult featureResul = featureQueryResult.get(); for (Object element : featureResul) { if (element instanceof Feature) { Feature mFeatureGrafic = (Feature) element; Geometry geometry=mFeatureGrafic.getGeometry(); GraphicsOverlay graphicsOverlay_1=new GraphicsOverlay(); SimpleMarkerSymbol pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.DIAMOND, Color.RED, 10); SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.DASH,Color.GREEN,10); SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID,Color.YELLOW,lineSymbol); Graphic pointGraphic = new Graphic(clickPoint,pointSymbol); Graphic fillGraphic = new Graphic(geometry,fillSymbol); graphicsOverlay_1.getGraphics().add(pointGraphic); graphicsOverlay_1.getGraphics().add(fillGraphic); mMapView.getGraphicsOverlays().add(graphicsOverlay_1); } } }catch (Exception e){ e.printStackTrace(); } } }); return true; } });
功能就是展示点击查询到对应的图层,找到这个面,并且设置为红点,绿线,黄面。我们看看效果图:
渲染Renderer使用
渲染也是设置图形样式,相比起符号来,渲染就相当于是批量的图形样式设置。但是当渲染和符号同时存在时候,会优先使用符号的样式
渲染一共包含了ClassBreaksRenderer, HeatmapRenderer, SimpleRenderer, UniqueValueRenderer, UnsupportedRenderer五大类,这里简要以SimpleRenderer介绍下吧。
使用方法其实上面介绍符号时候以及接触到了,以官方例子说明下:
// point graphic Point pointGeometry = new Point(40e5, 40e5, SpatialReferences.getWebMercator()); // red diamond point symbol SimpleMarkerSymbol pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.DIAMOND, Color.RED, 10); // create graphic for point Graphic pointGraphic = new Graphic(pointGeometry); // create a graphic overlay for the point GraphicsOverlay pointGraphicOverlay = new GraphicsOverlay(); // create simple renderer SimpleRenderer pointRenderer = new SimpleRenderer(pointSymbol); pointGraphicOverlay.setRenderer(pointRenderer); // add graphic to overlay pointGraphicOverlay.getGraphics().add(pointGraphic); // add graphics overlay to the MapView mMapView.getGraphicsOverlays().add(pointGraphicOverlay); // line graphic PolylineBuilder lineGeometry = new PolylineBuilder(SpatialReferences.getWebMercator()); lineGeometry.addPoint(-10e5, 40e5); lineGeometry.addPoint(20e5, 50e5); // solid blue line symbol SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 5); // create graphic for polyline Graphic lineGraphic = new Graphic(lineGeometry.toGeometry()); // create graphic overlay for polyline GraphicsOverlay lineGraphicOverlay = new GraphicsOverlay(); // create simple renderer SimpleRenderer lineRenderer = new SimpleRenderer(lineSymbol); // add graphic to overlay lineGraphicOverlay.setRenderer(lineRenderer); // add graphic to overlay lineGraphicOverlay.getGraphics().add(lineGraphic); // add graphics overlay to the MapView mMapView.getGraphicsOverlays().add(lineGraphicOverlay); //polygon graphic PolygonBuilder polygonGeometry = new PolygonBuilder(SpatialReferences.getWebMercator()); polygonGeometry.addPoint(-20e5, 20e5); polygonGeometry.addPoint(20e5, 20e5); polygonGeometry.addPoint(20e5, -20e5); polygonGeometry.addPoint(-20e5, -20e5); // solid yellow polygon symbol SimpleFillSymbol polygonSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.YELLOW, null); // create graphic for polygon Graphic polygonGraphic = new Graphic(polygonGeometry.toGeometry()); // create graphic overlay for polygon GraphicsOverlay polygonGraphicOverlay = new GraphicsOverlay(); // create simple renderer SimpleRenderer polygonRenderer = new SimpleRenderer(polygonSymbol); // add graphic to overlay polygonGraphicOverlay.setRenderer(polygonRenderer); // add graphic to overlay polygonGraphicOverlay.getGraphics().add(polygonGraphic); // add graphics overlay to MapView mMapView.getGraphicsOverlays().add(polygonGraphicOverlay);