POST
|
I have a C# Winforms application, containing a treeview with a bunch of maps. Clicking on a node, opens the specified map. I want to add some nodes with some predefinded filters, where i can parse SQL like the "Select By Attributes" tool, to only show specific parts of a maps. I'm still very new to Esri and arcmaps in general, and have no idea where to start with this. Any help would be appreciated.
... View more
01-28-2019
12:19 AM
|
0
|
0
|
247
|
POST
|
I have a form with a TreeView in which the user can select different maps to be loaded into ArcMap. The issue is that if clicking outside of the form window, the last selection gets "locked up", and then it keeps selecting that no matter where you click on the screen. I fixed it by displaying it with frm.showDialog(), but this is not a perfect scenario either. The options are being generated by a switch like this one: private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
ClsMaps wsf2 = (ClsMaps)new ClsMaps();
switch (e.Node.Name)
{
case "Option1":
tbMessages.Text = "Loading : " + e.Node.Name;
wsf2.GetMaps(@"Option1", @"Some\Path\To\Option1_geotiff\Somewhere", @"indesOption1", @"FilePath");
break;
case "Option2":
tbMessages.Text = "Loading : " + e.Node.Name;
wsf2.GetMaps(@"Option2", @"Some\Path\To\Option2_geotiff\Somewhere", @"indexOption2", @"FilePath");
break;
case "Option3":
tbMessages.Text = "Loading : " + e.Node.Name;
wsf2.GetMaps(@"Option3", @"Some\Path\To\Option3_geotiff\Somewhere", @"indexOption3", @"FilePath");
break;
case "Option4":
tbMessages.Text = "Loading : " + e.Node.Name;
wsf2.GetMaps(@"Option4", @"Some\Path\To\Option4_geotiff\Somewhere", @"indexOption4", @"FilePath");
break;
default:
tbMessages.Text = "Loading : " + e.Node.Name;
LoadLyrFromPath(e.Node.Name);
break;
}
treeView.SelectedNode = null;
} The switch is a lot bigger than this, but this is the structure, no reason to post the full length of it. The GetMaps method being called in most of the cases is this: public void GetMaps(string strGrpLayer, string strIndexPath, string strIndexName, string strIndexColonName, string strType = "TIF")
{
try
{
// delete grouplayer if it is already there
IActiveView activeView = ArcMap.Document.ActiveView;
IEnvelope envelope = activeView.Extent;
ESRI.ArcGIS.Carto.IMap focusMap1 = ArcMap.Document.FocusMap;
int layerCount1 = focusMap1.LayerCount;
for (int i = 0; i < layerCount1; i++)
{
ILayer layer = focusMap1.Layer[i];
string layerName = layer.Name;
if (layer is IGroupLayer && strGrpLayer.Equals(layerName))
{
ArcMap.Document.FocusMap.DeleteLayer(layer);
break;
}
}
//Open index map
IWorkspace ws = null;
IWorkspaceFactory wsf = (IWorkspaceFactory)new ShapefileWorkspaceFactory();
ws = wsf.OpenFromFile(strIndexPath, 0);
IFeatureWorkspace featureworkspace = (IFeatureWorkspace)ws;
IFeatureClass fc = featureworkspace.OpenFeatureClass(strIndexName);
// Create the spatial filter and set its spatial constraints.
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = envelope;
spatialFilter.GeometryField = fc.ShapeFieldName;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
IFeatureCursor featureCursor = fc.Search(spatialFilter, true);
IFeature Feat1 = featureCursor.NextFeature();
//Create grouplayer
IGroupLayer groupLayer1 = new GroupLayer();
groupLayer1.Name = strGrpLayer;
groupLayer1.Expanded = false;
//open a raster dataset from a file system
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesRaster.RasterWorkspaceFactory");
IWorkspaceFactory wsFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
int intNumFeatures = 0;
//Add all raster files to grouplayer
while (Feat1 != null)
{
//
int intColnr = Feat1.Fields.FindField(strIndexColonName);
string strTest = Feat1.get_Value(intColnr).ToString();
if (strTest.Length == 0 || strTest.Length == 1)
{ }
else
{
if (strType == "TIF" || strType == "AnotherStringType" || strType == "AThirdStringType")
{
string strPath = "";
string strFileName = "";
if (strType == "TIF")
{
strPath = System.IO.Path.GetDirectoryName(strTest);
strFileName = System.IO.Path.GetFileName(strTest);
}
else if (strType == "AnotherStringType")
{
strPath = @"Some\Path\To\Somewhere";
strFileName = strTest;
}
else if (strType == "AThirdStringType")
{
strPath = @"Some\Path\To\Somewhere";
strFileName = strTest;
}
if (File.Exists(strPath + "\\" + strFileName))
{
IRasterWorkspace2 rasterWS = (IRasterWorkspace2)wsFactory.OpenFromFile(strPath, 4);
IRasterDataset rds = rasterWS.OpenRasterDataset(strFileName);
IRasterLayer rasterLayer = new RasterLayerClass();
rasterLayer.CreateFromDataset(rds);
if (strGrpLayer == "SomeGroupLayer")
////show sentinel2 correct
{
RasterRGBRendererClass rasterRGBRenderer1 = new RasterRGBRendererClass();
rasterRGBRenderer1.StretchType = esriRasterStretchTypesEnum.esriRasterStretch_NONE;
rasterRGBRenderer1.UseGamma = true;
rasterRGBRenderer1.RedBandIndex = 3;
rasterRGBRenderer1.GreenBandIndex = 0;
rasterRGBRenderer1.BlueBandIndex = 3;
// laver array af doubles med 3 pladser, og tilføjer 1 til index 0, 2 til index 1 og 1 til index 2
double[] gammas = new double[3];
gammas[0] = 4;
gammas[1] = 3;
gammas[2] = 2;
rasterRGBRenderer1.GammaValue = gammas;
rasterLayer.Renderer = rasterRGBRenderer1;
}
//add raster to grouplayer
groupLayer1.Add(rasterLayer);
}
else
{
MessageBox.Show("Denne fil kan ikke findes : " + strPath + "\\" + strFileName + System.Environment.NewLine + " Kontakt en skriftklog og han kan hjælpe dig. Husk kontanter !");
}
}
else if (strType == "SHP")
{
//strTest = System.IO.Directory.GetParent(strIndexPath).ToString() + "\\" + strTest;
string[] filePaths = System.IO.Directory.GetFiles(strTest, "*.shp");
int i2 = filePaths.Count();
for (int i = 0; i <= i2 - 1; i++)
{
string strPath2 = filePaths[i];
string strPath = System.IO.Path.GetDirectoryName(strPath2);
string strFileName = System.IO.Path.GetFileName(strPath2);
IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactoryClass();
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)
workspaceFactory.OpenFromFile(strPath, 0);
// Create a new FeatureLayer and assign a shapefile to it
IFeatureLayer featureLayer = new FeatureLayerClass();
featureLayer.FeatureClass = featureWorkspace.OpenFeatureClass(strFileName);
ILayer layer = (ILayer)featureLayer;
layer.Name = featureLayer.FeatureClass.AliasName;
groupLayer1.Add(layer);
}
}
}
intNumFeatures = intNumFeatures + 1;
Feat1 = featureCursor.NextFeature();
if (intNumFeatures == 10)
{
var varResultat = MessageBox.Show(@"There is more then 10 images in this request. Do you want to load all images?", "Header", MessageBoxButtons.YesNo);
// If the no button was pressed ...
if (varResultat == DialogResult.No)
{
// cancel the closure of the form.
break;
}
}
}
//add grouplayer to arcgis
ArcMap.Document.FocusMap.AddLayer(groupLayer1);
ArcMap.Document.FocusMap.MoveLayer(groupLayer1, ArcMap.Document.FocusMap.LayerCount - 1);
}
catch (InvalidCastException e)
{
MessageBox.Show(e.Message);
}
}
The method being called in the default is this: public void LoadLyrFromPath(string strPath2)
{
try
{
if (!System.IO.File.Exists(strPath2)) return;
IActiveView activeView = ArcMap.Document.ActiveView;
IMap map = activeView.FocusMap;
IGxLayer gxLayerCls = new GxLayer();
IGxFile gxFile = (IGxFile)gxLayerCls;
//Set the path for where the layer file is located on disk.
gxFile.Path = strPath2;
map.AddLayer(gxLayerCls.Layer);
map.MoveLayer(gxLayerCls.Layer, map.LayerCount - 1);
}
catch (InvalidCastException e)
{
tbMessages.Text = e.Message;
}
}
... View more
12-17-2018
01:49 AM
|
0
|
0
|
365
|
POST
|
I'm helping a colleague debug a tool he is creating for ArcMap. It is used to create Replicas, and is done through selecting some different inputs from dropdowns in a winform. The issue is that when running all the code on the UI-thread, our ui freezes. This is what he wants me to solve. The code causing this is the following, the relevant code is just the button1_Click_1() method, but i provided the second class for context: public partial class FrmReplicaAdmin : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
DataConnectionConfig selectedDatabase = cmboxDatabase.SelectedItem as DataConnectionConfig;
if (selectedDatabase.PlWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (PL)";
return;
}
if (selectedDatabase.DataWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (NIS)";
return;
}
int scaleBand = int.Parse(cmboxScale.SelectedItem.ToString());
string gridName = cmboxGridNr.SelectedItem as string;
IGeometry shapeOfSelectedAOI = getSelectedPolygon(gridName, scaleBand, selectedDatabase);
(ArcMap.Application as IMxApplication2).PauseDrawing = true;
replica.CheckOutReplica(selectedDatabase.PlWorkspace, selectedDatabase.DataWorkspace, selectedDatabase.TemplateGdb, gridName, scaleBand, shapeOfSelectedAOI, selectedDatabase.DatasetName);
(ArcMap.Application as IMxApplication2).PauseDrawing = false;
}
}
public class Replica
{
public void CheckOutReplica(IWorkspace plWorkspace, IWorkspace parentWorkspace, string pathToDatabaseTemplate, string gridName, int scaleBand, IGeometry shapeOfSelectedAOI, string datasetName = "NIS.Nautical")
{
try
{
string replicaName = string.Format("{0}_{1}_r", Environment.UserName, gridName);
string versionName = string.Format("{0}_{1}", Environment.UserName, gridName);
string pathToLocalChildDatabase = System.IO.Path.Combine(ReplicationPath, $"{replicaName}.gdb");
Directory.CreateDirectory(pathToLocalChildDatabase);
foreach (string newPath in Directory.GetFiles(pathToDatabaseTemplate, "*.*", SearchOption.AllDirectories))
File.Copy(newPath, newPath.Replace(pathToDatabaseTemplate, pathToLocalChildDatabase), true);
IWorkspace childWorkspace = OpenWorkspace(pathToLocalChildDatabase);
// Create Version in ParentDatabase
IEnumVersionInfo versionEnum = (parentWorkspace as IVersionedWorkspace).Versions;
versionEnum.Reset();
for (IVersionInfo versionInfo = versionEnum.Next(); versionInfo != null; versionInfo = versionEnum.Next())
{
if (versionInfo.VersionName.EndsWith(versionName))
{
System.Windows.Forms.MessageBox.Show("A version named '" + versionName + "' has already been created", "map...", System.Windows.Forms.MessageBoxButtons.OK);
return;
}
}
Marshal.ReleaseComObject(versionEnum);
IVersion newVersion = (parentWorkspace as IVersionedWorkspace).DefaultVersion.CreateVersion(versionName);
newVersion.Access = esriVersionAccess.esriVersionAccessPublic;
string defQuery = "((IS_CONFLATE=1 AND PLTS_COMP_SCALE >= " + scaleBand + ") OR ((IS_CONFLATE=0 OR IS_CONFLATE IS NULL) AND PLTS_COMP_SCALE = " + scaleBand + "))";
ReplicateData(parentWorkspace, newVersion.VersionInfo, replicaName, shapeOfSelectedAOI, childWorkspace, defQuery, datasetName);
// Update map. Show replica data
ILayerFile nauticalLyrFile = new LayerFileClass();
nauticalLyrFile.Open(ReplicationPath + @"\Nautical.lyr");
AddDataToMap((ArcMap.Application.Document as IMxDocument), childWorkspace as IFeatureWorkspace, nauticalLyrFile, gridName, datasetName);
(ArcMap.Application.Document as IMxDocument).ActiveView.Extent = shapeOfSelectedAOI.Envelope;
Marshal.ReleaseComObject(childWorkspace);
}
catch (Exception err)
{
System.Windows.Forms.MessageBox.Show($"Unexpected error. {Environment.NewLine}{err.Message}", "map...", System.Windows.Forms.MessageBoxButtons.OK);
}
}
}
private void ReplicateData(IWorkspace parentWorkspace, IVersionInfo versionInfo, string replicaName, IGeometry area, IWorkspace childWorkspace, string definitionQuery, string featureDataset)
{
if (childWorkspace == null)
throw new ArgumentNullException("Child workspace is null.");
if (parentWorkspace == null)
throw new ArgumentNullException("Parent workspace is null.");
if (versionInfo == null)
throw new ArgumentNullException("Version name is null.");
if (string.IsNullOrEmpty(replicaName))
throw new ArgumentNullException("Replica name is null.");
if (area == null)
throw new ArgumentNullException("Area geometry is null.");
IVersion oVersion = (parentWorkspace as IVersionedWorkspace).FindVersion(versionInfo.VersionName);
IWorkspace sdeVersionWorkspace = oVersion as IWorkspace;
IGeoDataServer parentGds = InitGeoDataServer(sdeVersionWorkspace),
childGds = InitGeoDataServer(childWorkspace);
CreateFeatureDatasetReplica(parentGds, childGds, versionInfo, replicaName, parentWorkspace, childWorkspace, area, definitionQuery, featureDataset);
Marshal.ReleaseComObject(parentGds);
Marshal.ReleaseComObject(childGds);
}
//Function to create the replica, based on this link http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//0001000003r5000000
private void CreateFeatureDatasetReplica(IGeoDataServer parentGDS, IGeoDataServer childGDS, IVersionInfo versionInfo, string replicaName, IWorkspace parentWorkspace, IWorkspace childWorkspace, IGeometry geometry, string definitionQuery, string featureDatasetName)
{
IList<string> existingReplicas = ReadExistingReplicas(parentGDS);
if (existingReplicas.Contains(replicaName.ToUpper()))
{
throw new Exception("A replica with the following name has already been created: " + replicaName);
}
IEnumDataset datasets = null;
if (!string.IsNullOrEmpty(featureDatasetName))
{
IEnumDataset featureDatasets = parentWorkspace.get_Datasets(esriDatasetType.esriDTFeatureDataset);
IFeatureDataset featureDataset;
while ((featureDataset = featureDatasets.Next() as IFeatureDataset) != null)
{
if (featureDataset.Name == featureDatasetName)
{
datasets = featureDataset.Subsets;
break;
}
}
if (datasets == null)
throw new Exception("Didn't find FeatureDataset " + featureDatasetName + " in the db");
}
else
{
datasets = parentWorkspace.get_Datasets(esriDatasetType.esriDTFeatureClass);
}
IGPReplicaDatasets gpReplicaDatasets = new GPReplicaDatasetsClass();
IDataset dataset;
while ((dataset = datasets.Next()) != null)
{
//temporary workaround to not include a view that is on the feature classes :^)
if (dataset.Name.Contains("VW_") || dataset.Name.Contains("_EVW"))
continue;
if (m_ListExcludedTables.Contains(dataset.Name.Substring(dataset.Name.LastIndexOf(".") + 1).ToUpper()))
continue;
if (!(childWorkspace as IWorkspace2).NameExists[dataset.Type, dataset.Name.Substring(dataset.Name.LastIndexOf(".") + 1)])
continue;
IGPReplicaDataset gpReplicaDataset = new GPReplicaDatasetClass();
gpReplicaDataset.DatasetType = dataset.Type;
gpReplicaDataset.Name = dataset.Name.ToUpper();
gpReplicaDataset.IsPrivate = false;
gpReplicaDataset.UseGeometry = true;
gpReplicaDataset.RowsType = esriRowsType.esriRowsTypeFilter;
if ((dataset as ITable).Fields.FindField("PLTS_COMP_SCALE") != -1)
gpReplicaDataset.DefQuery = definitionQuery; //DefQuery here
else
gpReplicaDataset.DefQuery = "";
gpReplicaDatasets.Add(gpReplicaDataset);
}
IGPReplicaDescription gpReplicaDesc = new GPReplicaDescriptionClass();
gpReplicaDesc.QueryGeometry = geometry;
gpReplicaDesc.SpatialRelation = esriSpatialRelEnum.esriSpatialRelIntersects;
gpReplicaDesc.ModelType = esriReplicaModelType.esriModelTypeSimple;
gpReplicaDesc.SingleGeneration = true;
gpReplicaDesc.ReplicaDatasets = gpReplicaDatasets;
IGPReplicaOptions2 replicaOptions = new GPReplicaOptionsClass();
replicaOptions.AccessType = esriReplicaAccessType.esriReplicaAccessNone;
replicaOptions.RegisterReplicaOnly = true;
ExtractData(datasets, childWorkspace, geometry, definitionQuery);
IReplicationAgent replicationAgent = new ReplicationAgentClass();
replicationAgent.CreateReplica(versionInfo.VersionName, parentGDS, childGDS, replicaName, gpReplicaDesc, replicaOptions);
}
} For fixing the UI freeze i made the following changes to the button1_Click_1() method: public partial class FrmReplicaAdmin : Form
{
private void button1_Click_1(object sender, EventArgs e)
{
DataConnectionConfig selectedDatabase = cmboxDatabase.SelectedItem as DataConnectionConfig;
if (selectedDatabase.PlWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (PL)";
return;
}
if (selectedDatabase.DataWorkspace == null)
{
statusLabel.Text = "Could not open GeoDatabase (NIS)";
return;
}
int scaleBand = int.Parse(cmboxScale.SelectedItem.ToString());
string gridName = cmboxGridNr.SelectedItem as string;
IGeometry shapeOfSelectedAOI = getSelectedPolygon(gridName, scaleBand, selectedDatabase);
// adding inputs to list i can pass onto the backgroundWorker
List<object> arguments = new List<object>();
arguments.Add(selectedDatabase.PlWorkspace);
arguments.Add(selectedDatabase.DataWorkspace);
arguments.Add(selectedDatabase.TemplateGdb);
arguments.Add(gridName);
arguments.Add(scaleBand);
arguments.Add(shapeOfSelectedAOI);
arguments.Add(selectedDatabase.DatasetName);
backgroundWorker1.RunWorkerAsync(arguments);
// starting progress bar
progressBarReplica.Visible = true;
lblReplica.Text = "Checking out replica...";
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
List<object> genericlist = e.Argument as List<object>;
IWorkspace ws = (IWorkspace)genericlist[0];
IWorkspace pWs = (IWorkspace)genericlist[1];
string pathToDbTemplate = genericlist[2].ToString();
string gName = genericlist[3].ToString();
int sBand = (int)genericlist[4];
IGeometry shape = (IGeometry)genericlist[5];
string dsName = genericlist[6].ToString();
(ArcMap.Application as IMxApplication2).PauseDrawing = true;
replica.CheckOutReplica(ws, pWs, pathToDbTemplate, gName, sBand, shape, dsName);
(ArcMap.Application as IMxApplication2).PauseDrawing = false;
}
} This is causing a: "RPC_E_SERVERFAULT(0X80010105)", but the UI isn't freezing anymore. My guess is that it's because i'm initiating the database in the first thread, and then using it in the second. I also sort of get that i can't use a backgroundWorker due to the entire STA and COM-object things with ArcGis, but i'm still not getting all this 100%. Any help of a possible solution to making my UI responsive, or at least showing some sort of progressbar while the task is running would be nice. The entire process can take a few minutes at times, and the program feels like it's crashed meanwhile due to the freeze. Edit: I'm referring to ArcMap, forgot to mention that.
... View more
12-09-2018
02:38 AM
|
0
|
1
|
548
|
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:25 AM
|