Skip to content

Commit

Permalink
Prototype 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel-Butt committed Jun 13, 2024
1 parent bae1e90 commit 1fd2864
Show file tree
Hide file tree
Showing 14 changed files with 1,160 additions and 59 deletions.
229 changes: 229 additions & 0 deletions MESH_MAP/FeatureClassBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
using ArcGIS.Desktop.Core.Geoprocessing;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ArcGIS.Core.Geometry;
using ArcGIS.Core.Data;
using ArcGIS.Desktop.Mapping;
using System.Threading;
using System.Windows;
using ArcGIS.Desktop.Editing;
using ArcGIS.Core.Data.UtilityNetwork.Trace;
using ArcGIS.Core.Internal.Geometry;
using ArcGIS.Core.Data.Raster;

namespace MESH_MAP
{
internal class FeatureClassBuilder
{
public static async Task<FeatureLayer> CreateFcWithAttributes(string fcName, FeatureClassType fcType, List<Attribute> attributes, int spatialReference=3857)
{
// Create feature class T1
await CreateFeatureClass(fcName, fcType, spatialReference);
// double check to see if the layer was added to the map
var fcLayer = MapView.Active.Map.GetLayersAsFlattenedList().Where((l) => l.Name == fcName).FirstOrDefault() as FeatureLayer;
if (fcLayer == null)
{
MessageBox.Show($@"Unable to find {fcName} in the active map");
return null;
}

var dataSource = await GetDataSource(fcLayer);

foreach (var attribute in attributes)
{
await ExecuteAddFieldToolAsync(fcLayer, new KeyValuePair<string, string>(attribute.Name, attribute.Description), attribute.Type.ToString(), 50);
}

return fcLayer;
}

public enum AttributeType
{
TEXT,
DOUBLE,
LONG
}

public struct Attribute
{
public string Name { get; set; }
public string Description { get; set; }
public AttributeType Type { get; set; }

public Attribute(string name, string description, AttributeType type)
{
Name = name;
Description = description;
Type = type;
}
}

public enum FeatureClassType
{
POINT,
MULTIPOINT,
POLYLINE,
POLYGON
}

public static async Task<Geometry> CreatePolygon (OpenCvSharp.Point[] pts, RasterLayer rasterLayer)
{
Polygon p = null;
List<MapPoint> mapPts = [];

await QueuedTask.Run(() =>
{
Raster raster = rasterLayer.GetRaster();

foreach (var pt in pts)
{
var coordPt = raster.PixelToMap(pt.X, pt.Y);
mapPts.Add(MapPointBuilderEx.CreateMapPoint(coordPt.Item1, coordPt.Item2));
}

p = PolygonBuilder.CreatePolygon(mapPts.ToArray());
});

return p;
}

public static async Task AddFeatures(string featureclassName, List<Dictionary<string, object>> features)
{
var layer = MapView.Active.Map.GetLayersAsFlattenedList().Where((l) => l.Name == featureclassName).FirstOrDefault();

await QueuedTask.Run(() =>
{
var editOp = new EditOperation
{
Name = "edit operation"
};

foreach (var feature in features)
{
editOp.Create(layer, feature);
}
var result = editOp.Execute();

if (result != true || editOp.IsSucceeded != true)
{
MessageBox.Show("Error: Could not edit feature layer " + featureclassName);
}
});

await Project.Current.SaveEditsAsync();
}


public static async Task CreateFeatureClass(string featureclassName, FeatureClassType featureclassType, int spatialReference=3857)
{
List<object> arguments = new List<object>
{
// store the results in the default geodatabase
CoreModule.CurrentProject.DefaultGeodatabasePath,
// name of the feature class
featureclassName,
// type of geometry
featureclassType.ToString(),
// no template
"",
// no z values
"DISABLED",
// no m values
"DISABLED"
};
await QueuedTask.Run(() =>
{
// spatial reference
arguments.Add(SpatialReferenceBuilder.CreateSpatialReference(spatialReference));
});
IGPResult result = await Geoprocessing.ExecuteToolAsync("CreateFeatureclass_management", Geoprocessing.MakeValueArray(arguments.ToArray()));
}

public static async Task<string> GetDataSource(BasicFeatureLayer theLayer)
{
try
{
return await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
var inTable = theLayer.Name;
var table = theLayer.GetTable();
var dataStore = table.GetDatastore();
var workspaceNameDef = dataStore.GetConnectionString();
var workspaceName = workspaceNameDef.Split('=')[1];
var fullSpec = System.IO.Path.Combine(workspaceName, inTable);
return fullSpec;
});
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return string.Empty;
}
}

public static async Task<string> ExecuteAddFieldToolAsync(
BasicFeatureLayer theLayer,
KeyValuePair<string, string> field,
string fieldType, int? fieldLength = null,
bool isNullable = true)
{
return await QueuedTask.Run(() =>
{
try
{
var inTable = theLayer.Name;
var table = theLayer.GetTable();
var dataStore = table.GetDatastore();
var workspaceNameDef = dataStore.GetConnectionString();
var workspaceName = workspaceNameDef.Split('=')[1];

var fullSpec = System.IO.Path.Combine(workspaceName, inTable);
System.Diagnostics.Debug.WriteLine($@"Add {field.Key} from {fullSpec}");

var parameters = Geoprocessing.MakeValueArray(fullSpec, field.Key, fieldType.ToUpper(), null, null, fieldLength, field.Value, isNullable ? "NULABLE" : "NON_NULLABLE");
var cts = new CancellationTokenSource();
var results = Geoprocessing.ExecuteToolAsync("management.AddField", parameters, null, cts.Token,
(eventName, o) =>
{
System.Diagnostics.Debug.WriteLine($@"GP event: {eventName}");
});
var isFailure = results.Result.IsFailed || results.Result.IsCanceled;
return !isFailure ? "Failed" : "Ok";
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return ex.ToString();
}
});
}

public static Task<bool> FeatureClassExistsAsync(string fcName)
{
return QueuedTask.Run(() =>
{
try
{
using (Geodatabase projectGDB = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(Project.Current.DefaultGeodatabasePath))))
{
using (FeatureClass fc = projectGDB.OpenDataset<FeatureClass>(fcName))
{
return fc != null;
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($@"FeatureClassExists Error: {ex.ToString()}");
return false;
}
});
}

}
}
20 changes: 10 additions & 10 deletions MESH_MAP/LengthReqsBox.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MESH_MAP"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="520">
d:DesignHeight="150" d:DesignWidth="535">
<Grid>
<Rectangle HorizontalAlignment="Left" Height="150" Fill="#F7F8F8" VerticalAlignment="Top" Width="520"/>
<ListBox x:Name="lengthReqsListBox" Margin="5,5,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="350" Height="110"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="100,125,0,0" VerticalAlignment="Top" Width="50" Click="AddItem"/>
<Button Content="Delete" HorizontalAlignment="Left" Margin="200,125,0,0" VerticalAlignment="Top" Width="50" Click="DeleteItem"/>
<Label Content="Hail Size" FontSize="14" HorizontalAlignment="Left" Margin="369,24,0,0" VerticalAlignment="Top"/>
<Label Content="Length" FontSize="14" HorizontalAlignment="Left" Margin="448,24,0,0" VerticalAlignment="Top"/>
<local:WholeNumBox x:Name="lengthBox" HorizontalAlignment="Left" Margin="454,53,0,0" VerticalAlignment="Top" Width="40" Height="22" RenderTransformOrigin="0.514,0.655" DefaultValue="10"/>
<Label Content="Km" FontSize="12" HorizontalAlignment="Left" Margin="491,53,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.143,0.519"/>
<ComboBox x:Name="hailSizeComboBox" Margin="360,53,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Height="20" SelectedIndex="5">
<Rectangle HorizontalAlignment="Left" Height="150" Fill="#eff0f1" VerticalAlignment="Top" Width="535"/>
<ListBox x:Name="lengthReqsListBox" Margin="5,5,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" Height="110"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="75,125,0,0" VerticalAlignment="Top" Width="50" Click="AddItem"/>
<Button Content="Delete" HorizontalAlignment="Left" Margin="175,125,0,0" VerticalAlignment="Top" Width="50" Click="DeleteItem"/>
<Label Content="Hail Size" FontSize="14" HorizontalAlignment="Left" Margin="346,24,0,0" VerticalAlignment="Top"/>
<Label Content="Length" FontSize="14" HorizontalAlignment="Left" Margin="442,23,0,0" VerticalAlignment="Top"/>
<local:WholeNumBox x:Name="lengthBox" HorizontalAlignment="Left" Margin="443,52,0,0" VerticalAlignment="Top" Width="50" Height="22" RenderTransformOrigin="0.514,0.655" DefaultValue="10"/>
<Label Content="Km" FontSize="12" HorizontalAlignment="Left" Margin="492,50,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.143,0.519"/>
<ComboBox x:Name="hailSizeComboBox" Margin="337,53,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Height="20" SelectedIndex="5">
<ComboBoxItem>
<StackPanel Orientation="Horizontal">
<Rectangle Stroke="#000000" Width="10" Height="10" Fill="#0099ff"/>
Expand Down
17 changes: 17 additions & 0 deletions MESH_MAP/MESH_MAP.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<NoWarn>CA1416</NoWarn>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<None Remove="Config.daml" />
Expand All @@ -21,6 +22,11 @@
<ItemGroup>
<None Include="Properties\launchSettings.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="OpenCvSharp4" Version="4.9.0.20240103" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.9.0.20240103" />
<PackageReference Include="QuikGraph" Version="2.5.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="ArcGIS.Desktop.Framework">
<HintPath>C:\Program Files\ArcGIS\Pro\bin\ArcGIS.Desktop.Framework.dll</HintPath>
Expand Down Expand Up @@ -97,6 +103,17 @@
<CopyLocal>False</CopyLocal>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<None Update="OpenCvSharp.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="OpenCvSharpExtern.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="opencv_videoio_ffmpeg490_64.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="C:\Program Files\ArcGIS\Pro\bin\Esri.ProApp.SDK.Desktop.targets" Condition="Exists('C:\Program Files\ArcGIS\Pro\bin\Esri.ProApp.SDK.Desktop.targets') AND !Exists('Esri.ArcGISPro.Extensions.targets')" />
</Project>
8 changes: 7 additions & 1 deletion MESH_MAP/MESH_MAP.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MESH_MAP", "MESH_MAP.csproj", "{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MESH_MAP", "MESH_MAP.csproj", "{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Debug|x64.ActiveCfg = Debug|x64
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Debug|x64.Build.0 = Debug|x64
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Release|Any CPU.Build.0 = Release|Any CPU
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Release|x64.ActiveCfg = Release|x64
{0DE63514-EB3B-457C-8F5C-D9EE48C9BF5C}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit 1fd2864

Please sign in to comment.