• AddOverlay和删除


    Skip to content
    
        Product 
    
    Team
    Enterprise
    Explore
    Marketplace
    Pricing
    
    Sign in
    Sign up
    Esri /
    arcgis-pro-sdk-community-samples
    Public
    
    Code
    Issues 2
    Pull requests 1
    Actions
    Projects
    Wiki
    Security
    
        Insights
    
    arcgis-pro-sdk-community-samples/Map-Exploration/OverlayGroundSurface/Module1.cs /
    @arcgisprosdk
    arcgisprosdk ArcGIS Pro SDK 2.7 SDK for .NET
    Latest commit 44183d0 on 16 Dec 2020
    History
    1 contributor
    531 lines (474 sloc) 18.8 KB
    /*
       Copyright 2020 Esri
       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at
           http://www.apache.org/licenses/LICENSE-2.0
       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.
    */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Input;
    using System.Threading.Tasks;
    using ArcGIS.Core.CIM;
    using ArcGIS.Core.Data;
    using ArcGIS.Core.Geometry;
    using ArcGIS.Desktop.Catalog;
    using ArcGIS.Desktop.Core;
    using ArcGIS.Desktop.Editing;
    using ArcGIS.Desktop.Extensions;
    using ArcGIS.Desktop.Framework;
    using ArcGIS.Desktop.Framework.Contracts;
    using ArcGIS.Desktop.Framework.Dialogs;
    using ArcGIS.Desktop.Framework.Threading.Tasks;
    using ArcGIS.Desktop.Mapping;
    
    namespace OverlayGroundSurface
    {
      /// <summary>
      /// OverlayGroundSurface illustrates how to draw geometries over a ground surface using AddOverlay.  
      /// </summary>
      /// <remarks>
      /// 1. Download the Community Sample data (see under the 'Resources' section for downloading sample data).  The sample data contains a folder called 'C:\Data\Configurations\Projects' with sample data required for this solution.  Make sure that the Sample data (specifically CommunitySampleData-3D-mm-dd-yyyy.zip) is unzipped into c:\data and c:\data\PolyTest is available.
      /// 1. This solution is using the **Newtonsoft.Json NuGet**.  If needed, you can install the NuGet from the "NuGet Package Manager Console" by using this script: "Install-Package Newtonsoft.Json".
      /// 1. In Visual Studio click the Build menu. Then select Build Solution.
      /// 1. Click Start button to debug ArcGIS Pro.
      /// 1. Open the Pro project file: PolyTest.aprx in the C:\Data\PolyTest\ folder.  Open the 'Graphic Test' tab in ArcGIS Pro.
      /// ![UI](Screenshots/Screen1.png)
      /// 1. Make sure that the 'Scene' is selected as the active map in ArcGIS Pro and then click on the 'Create 3D Polygon Tool'.
      /// 1. Digitize a polygon on the map.  Once a polygon has been digitized the buttons under the 'Polygon 2 Graphic' group are now enabled.  These buttons can be used to 'slice' the digitized polygon into smaller parts.
      /// ![UI](Screenshots/Screen2.png)
      /// 1. Note that the number of slices across the X axis can be controlled with the Resolution pull-down.  The 'Elevation' pull-down can be used add an additional elevation offset to the Z axis when the polygon is rendered in a scene.
      /// 1. Select: Resolution 4 and Elevation 5 on the respective pull-down and click the 'Make Ring MultiPatch' button.
      /// 1. The Add-in now converts the digitized polygon into a multipatch geometry and renders the multipatch in 2D and 3D.
      /// ![UI](Screenshots/Screen3.png)
      /// 1. Select: Resolution 50 and Elevation 20 on the respective pull-down and click the 'Make Ring MultiPatch' button.
      /// 1. The Add-in now converts the digitized polygon into a higher resolution multipatch geometry and renders the multipatch in 3D and 3D.
      /// ![UI](Screenshots/Screen4.png)
      /// </remarks>
      internal class Module1 : Module
      {
        private static Module1 _this = null;
    
        /// <summary>
        /// Retrieve the singleton instance to this module here
        /// </summary>
        public static Module1 Current
        {
          get
          {
            return _this ?? (_this = (Module1)FrameworkApplication.FindModule("OverlayGroundSurface_Module"));
          }
        }
    
        internal static MapView CurrentMapView { get; set; }
    
        #region UI properties and states
    
        private static List<Geometry> _geometries = new List<Geometry>();
        private static bool _hasImportData = false;
    
        internal static bool HasImportData
        {
          get { return _hasImportData; }
          set { _hasImportData = value; }
        }
    
        internal static bool HasGeometries
        {
          get { return HasImportData && _geometries.Count > 0; }
        }
    
        internal static List<Geometry> Geometries
        {
          get
          {
            return _geometries;
          }
          set
          {
            if (value == null) _geometries = null;
            else
            {
              _geometries.Clear();
              if (value != null)
              {
                foreach (var geom in value)
                {
                  _geometries.Add(geom.Clone());
                }
              }
            }
            SetState("has_geometry_state", _geometries != null && _geometries.Count > 0);
          }
        }
    
        private static Polygon _polygon = null;
    
        internal static Polygon Polygon
        {
          get
          {
            return _polygon;
          }
          set
          {
            if (value == null) _polygon = null;
            else _polygon = value.Clone() as Polygon;
            SetState("has_polygon_state", _polygon != null);
            foreach (var mv in _graphics.Keys)
            {
              ClearGraphics(mv);
            }
            var mvs = new List<MapView>();
            foreach (var mv in _graphic.Keys)
            {
              if (_graphic[mv] != null) mvs.Add(mv);
            }
            foreach (var mv in mvs)
            {
              _graphic[mv]?.Dispose();
              _graphic[mv] = null;
            }
            HasImportData = false;
          }
        }
    
        internal static void SetState(string stateName, bool active)
        {
          if (FrameworkApplication.State.Contains(stateName) == active) return;
          // toggle the state
          if (FrameworkApplication.State.Contains(stateName))
          {
            //deactivates the state
            FrameworkApplication.State.Deactivate(stateName);
          }
          else
          {
            //activates the state
            FrameworkApplication.State.Activate(stateName);
          }
        }
    
        internal static double Resolution { get; set; } = 1.00;
    
        internal static double Elevation { get; set; } = 1.00;
    
        #endregion UI properties and states
    
        #region Overlay Helpers
    
        private static Dictionary<MapView, IDisposable> _graphic = new Dictionary<MapView, IDisposable>();
    
        internal static void AddOrUpdateOverlay(Geometry geom, CIMSymbolReference symRef)
        {
          var mapView = Module1.CurrentMapView;
          if (mapView == null) return;
          ClearGraphics(mapView);
          if (!_graphic.ContainsKey(mapView))
          {
            _graphic.Add(mapView, mapView.AddOverlay(geom, symRef));
            return;
          }
          if (_graphic[mapView] == null)
          {
            if (geom is Multipatch)
            {
              var cimMpGraphic = new CIMMultiPatchGraphic
              {
                MultiPatch = geom as Multipatch,
                Symbol = symRef,
                Transparency = 64
              };
              _graphic[mapView] = mapView.AddOverlay(geom, symRef);
            }
            else
              _graphic[mapView] = mapView.AddOverlay(geom, symRef);
          }
          else
            mapView.UpdateOverlay(_graphic[mapView], geom, symRef);
        }
    
        internal static void ClearGraphic(MapView mapView)
        {
          if (mapView == null) return;
          if (_graphic.ContainsKey(mapView))
          {
            _graphic[mapView]?.Dispose();
            _graphic[mapView] = null;
          }
        }
    
        private static Dictionary<MapView, List<IDisposable>> _graphics = new Dictionary<MapView, List<IDisposable>>();
    
        private static void ClearGraphics(MapView mapView)
        {
          if (_graphics.ContainsKey(mapView))
          {
            foreach (var g in _graphics[mapView]) g.Dispose();
            _graphics[mapView].Clear();
          }
        }
    
        internal static void MultiAddOrUpdateOverlay(bool bFirst, Geometry geom, CIMSymbolReference symRef)
        {
          var mapView = Module1.CurrentMapView;
          if (mapView == null) return;
          if (bFirst)
          {
            ClearGraphic(mapView);
            ClearGraphics(mapView);
          }
          if (!_graphics.ContainsKey(mapView))
          {
            _graphics.Add(mapView, new List<IDisposable>());
          }
          _graphics[mapView].Add(Module1.CurrentMapView?.AddOverlay(geom, symRef));
        }
    
        #endregion Overlay Helpers
    
        #region Utility Helpers
    
        internal static bool Is3D => (Module1.CurrentMapView?.ViewingMode == MapViewingMode.SceneGlobal || Module1.CurrentMapView?.ViewingMode == MapViewingMode.SceneLocal);
    
        internal static double GetFishnetIntervalDistance(Envelope env)
        {
          return ((env.XMax - env.XMin) + (env.XMax - env.XMin) * 0.01) / Resolution;
        }
    
        #endregion Utility Helpers
    
        #region Polygon Helpers
    
        internal static List<Geometry> MakeFishnetPolygons(Polygon inputPoly)
        {
          List<Geometry> polygons = new List<Geometry>();
          Envelope envPoly = inputPoly.Extent;
          var interval = GetFishnetIntervalDistance(envPoly);
          for (var dX = envPoly.XMin; dX < envPoly.XMax + interval; dX += interval)
          {
            for (var dY = envPoly.YMin; dY < envPoly.YMax + interval; dY += interval)
            {
              var cutEnv = EnvelopeBuilder.CreateEnvelope(dX, dY, dX + interval, dY + interval, envPoly.SpatialReference);
              if (GeometryEngine.Instance.Intersects(cutEnv, inputPoly))
              {
                var addPolygonPart = GeometryEngine.Instance.Clip(inputPoly, cutEnv);
                polygons.Add(addPolygonPart);
              }
            }
          }
          return polygons;
        }
    
        internal static Geometry MakeFishnetPolygon(Polygon inputPoly)
        {
          Envelope envPoly = inputPoly.Extent;
          var interval = GetFishnetIntervalDistance(envPoly);
          var pb = new PolygonBuilder(inputPoly.SpatialReference)
          {
            HasZ = true
          };
          for (var dX = envPoly.XMin; dX < envPoly.XMax + interval; dX += interval)
          {
            for (var dY = envPoly.YMin; dY < envPoly.YMax + interval; dY += interval)
            {
              var cutEnv = EnvelopeBuilder.CreateEnvelope(dX, dY, dX + interval, dY + interval, envPoly.SpatialReference);
              if (GeometryEngine.Instance.Intersects(cutEnv, inputPoly))
              {
                var addPolygonPart = GeometryEngine.Instance.Clip(inputPoly, cutEnv) as Polygon;
                if (addPolygonPart.Area < 0)
                {
                  System.Diagnostics.Debug.WriteLine($@"area: {addPolygonPart.Area}");
                }
                pb.AddPart(addPolygonPart.Points);
              }
            }
          }
          return pb.ToGeometry();
        }
    
        #endregion Polygon Helpers
    
        #region MultiPatch Helpers
    
        internal static async Task<Geometry> MakeFishnetMultiPatchAsync(Polygon inputPoly)
        {
          Envelope envPoly = inputPoly.Extent;
          var interval = GetFishnetIntervalDistance(envPoly);
    
          var mColor = System.Windows.Media.Colors.LightCyan;
          var materialRed = new BasicMaterial
          {
            Color = mColor,
            EdgeColor = mColor,
            EdgeWidth = 0
          };
          // create the multipatchBuilderEx object
          var mpb = new MultipatchBuilderEx();
          // create a list of patch objects
          var patches = new List<Patch>();
          for (var dX = envPoly.XMin; dX < envPoly.XMax + interval; dX += interval)
          {
            for (var dY = envPoly.YMin; dY < envPoly.YMax + interval; dY += interval)
            {
              var cutEnv = EnvelopeBuilder.CreateEnvelope(dX, dY, dX + interval, dY + interval,
                                                          envPoly.SpatialReference);
              if (GeometryEngine.Instance.Intersects(cutEnv, inputPoly))
              {
                var addPolygonPart = GeometryEngine.Instance.Clip(inputPoly, cutEnv) as Polygon;
                if (addPolygonPart.Area < 0)
                {
                  System.Diagnostics.Debug.WriteLine($@"area: {addPolygonPart.Area}");
                }
                var result = await Module1.CurrentMapView.Map.GetZsFromSurfaceAsync(addPolygonPart);
                if (result.Status == SurfaceZsResultStatus.Ok)
                {
                  addPolygonPart = GeometryEngine.Instance.Move(result.Geometry, 0, 0, Module1.Elevation) as Polygon;
                }
                var patch = mpb.MakePatch(esriPatchType.TriangleStrip);
                patch.Coords = GetPolygonAsTriangleStrip(addPolygonPart);
                patch.Material = materialRed;
                patches.Add(patch);
              }
            }
          }            // assign the patches to the multipatchBuilder
          mpb.Patches = patches;
          // call ToGeometry to get the multipatch
          return mpb.ToGeometry();
        }
    
        internal static async Task<Multipatch> MakeFishnetRingMultiPatchAsync(Polygon inputPoly)
        {
          Envelope envPoly = inputPoly.Extent;
          var interval = GetFishnetIntervalDistance(envPoly);
    
          var mColor = System.Windows.Media.Colors.LightCyan;
          var materialRed = new BasicMaterial
          {
            Color = mColor,
            EdgeColor = mColor,
            EdgeWidth = 0
          };
          // create the multipatchBuilderEx object
          var mpb = new MultipatchBuilderEx();
          // create a list of patch objects
          var patches = new List<Patch>();
          var first = true;
          for (var dX = envPoly.XMin; dX < envPoly.XMax + interval; dX += interval)
          {
            for (var dY = envPoly.YMin; dY < envPoly.YMax + interval; dY += interval)
            {
              var cutEnv = EnvelopeBuilder.CreateEnvelope(dX, dY, dX + interval, dY + interval,
                                                          envPoly.SpatialReference);
              if (GeometryEngine.Instance.Intersects(cutEnv, inputPoly))
              {
                var addPolygonPart = GeometryEngine.Instance.Clip(inputPoly, cutEnv) as Polygon;
                if (addPolygonPart.Area < 0)
                {
                  System.Diagnostics.Debug.WriteLine($@"area: {addPolygonPart.Area}");
                }
                var result = await Module1.CurrentMapView.Map.GetZsFromSurfaceAsync(addPolygonPart);
                if (result.Status == SurfaceZsResultStatus.Ok)
                {
                  addPolygonPart = GeometryEngine.Instance.Move(result.Geometry, 0, 0, Module1.Elevation) as Polygon;
                }
                var patch = mpb.MakePatch(first ? esriPatchType.FirstRing : esriPatchType.Ring);
                first = false;
                patch.InsertPoints(0, addPolygonPart.Points);
                patch.Material = materialRed;
                patches.Add(patch);
              }
            }
          }            // assign the patches to the multipatchBuilder
          mpb.Patches = patches;
          // call ToGeometry to get the multipatch
          return mpb.ToGeometry() as Multipatch;
        }
    
        internal static List<Coordinate3D> GetPolygonAsTriangleStrip(Polygon poly)
        {
          if (poly.PointCount < 4)
          {
            throw new Exception($@"Polygon 2 Triangle failed, too few vertices: {poly.PointCount}");
          }
          int maxPoints = poly.PointCount - 1;
          Coordinate3D[] coords = new Coordinate3D[maxPoints];
          int iNext = 0;
          foreach (var coord in poly.Copy3DCoordinatesToList())
          {
            if (iNext < maxPoints) coords[iNext++] = coord;
          }
          var lstCoords = new List<Coordinate3D>();
          int iTop = maxPoints - 1;
          int iBottom = 0;
          lstCoords.Add(DebugCoord(iBottom, coords[iBottom++]));
          lstCoords.Add(DebugCoord(iBottom, coords[iBottom++]));
          lstCoords.Add(DebugCoord(iTop, coords[iTop--]));
          var tick = true;
          for (; iTop >= iBottom; tick = !tick)
          {
            lstCoords.Add(tick ? DebugCoord(iBottom, coords[iBottom++]) : DebugCoord(iTop, coords[iTop--]));
          }
          // get the coordinates in triangle strip order
          return lstCoords;
        }
    
        internal static Coordinate3D DebugCoord(int idx, Coordinate3D coord)
        {
          // System.Diagnostics.Debug.WriteLine($@"Pnt: {idx} {coord.X} {coord.Y} {coord.Z} ");
          return coord;
        }
    
        /// <summary>
        /// Call from MCT.
        /// </summary>
        /// <returns></returns>
        internal static CIMSymbolReference GetDefaultMeshSymbol()
        {
          // find a 3d symbol
          var spi = Project.Current.GetItems<StyleProjectItem>().First(s => s.Name == "ArcGIS 3D");
          if (spi == null) return null;
          // create new structural features
          var style_item = spi.SearchSymbols(StyleItemType.MeshSymbol, "").FirstOrDefault(si => si.Name.StartsWith("Gray 40%"));
          var symbol = style_item?.Symbol as CIMMeshSymbol;
          if (symbol == null) return null;
          var meshSymbol = symbol.MakeSymbolReference();
          return meshSymbol;
        }
    
        #endregion MultiPatch Helpers
    
        #region Symbol Helpers
    
        private static CIMSymbolReference _polySymbolRef = null;
    
        internal static CIMSymbolReference GetPolygonSymbolRef()
        {
          if (_polySymbolRef != null) return _polySymbolRef;
          //Creating a polygon with a red fill and blue outline.
          CIMStroke outline = SymbolFactory.Instance.ConstructStroke(
               ColorFactory.Instance.BlueRGB, 2.0, SimpleLineStyle.Solid);
          _polySymbolRef = SymbolFactory.Instance.ConstructPolygonSymbol(
               ColorFactory.Instance.CreateRGBColor(255, 190, 190),
               SimpleFillStyle.Solid, outline).MakeSymbolReference();
          return _polySymbolRef;
        }
    
        private static CIMSymbolReference _lineSymbolRef = null;
    
        /// <summary>
        /// Get a line symbol
        /// Must be called from the MCT.  Use QueuedTask.Run.
        /// </summary>
        /// <returns></returns>
        internal static CIMSymbolReference GetLineSymbolRef()
        {
          if (_lineSymbolRef != null) return _lineSymbolRef;
          _lineSymbolRef = SymbolFactory.Instance.ConstructLineSymbol(
                              ColorFactory.Instance.RedRGB, 4,
                              SimpleLineStyle.Solid).MakeSymbolReference();
          return _lineSymbolRef;
        }
    
        private static CIMSymbolReference _point3DSymbolRef = null;
        private static CIMSymbolReference _point2DSymbolRef = null;
    
        internal static CIMSymbolReference GetPointSymbolRef()
        {
          if (Is3D)
          {
            if (_point3DSymbolRef != null) return _point3DSymbolRef;
            var pointSymbol = GetPointSymbol("ArcGIS 3D", @"Pushpin 2");
            CIMPointSymbol pnt3DSym = pointSymbol.Symbol as CIMPointSymbol;
            pnt3DSym.SetSize(200);
            pnt3DSym.SetRealWorldUnits(true);
            _point3DSymbolRef = pnt3DSym.MakeSymbolReference();
            return _point3DSymbolRef;
          }
          if (_point2DSymbolRef != null) return _point2DSymbolRef;
          CIMPointSymbol pntSym = SymbolFactory.Instance.ConstructPointSymbol(ColorFactory.Instance.RedRGB, 8, SimpleMarkerStyle.Circle);
          _point2DSymbolRef = pntSym.MakeSymbolReference();
          return _point2DSymbolRef;
        }
    
        private static SymbolStyleItem GetPointSymbol(string styleProjectItemName, string symbolStyleName)
        {
          var style3DProjectItem = Project.Current.GetItems<StyleProjectItem>().Where(p => p.Name == styleProjectItemName).FirstOrDefault();
          var symbolStyle = style3DProjectItem.SearchSymbols(StyleItemType.PointSymbol, symbolStyleName).FirstOrDefault();
          return symbolStyle;
        }
    
        #endregion Symbol Helper
    
        #region Overrides
        /// <summary>
        /// Called by Framework when ArcGIS Pro is closing
        /// </summary>
        /// <returns>False to prevent Pro from closing, otherwise True</returns>
        protected override bool CanUnload()
        {
          //TODO - add your business logic
          //return false to ~cancel~ Application close
          return true;
        }
    
        #endregion Overrides
    
      }
    }
    
        © 2022 GitHub, Inc.
    
        Terms
        Privacy
        Security
        Status
        Docs
        Contact GitHub
        Pricing
        API
        Training
        Blog
        About
    
    Loading complete
  • 相关阅读:
    日期格式不合法
    DataGridView的Scrollbar通過編程不能自動下滾
    Sourcesafe shadown backup
    共享目錄突然不工作 
    VS2005編譯后版本如何控制
    WebBrowser用作RichTextBox
    怎樣設定MS Reporting自動橫向列印
    VSS 2005不需登錄,直接開啟的方法
    subreport cannot be shown
    An Algorithm Summary of Programming Collective Intelligence (5)
  • 原文地址:https://www.cnblogs.com/gisoracle/p/16268040.html
Copyright © 2020-2023  润新知