Hi,
I'm using the following code to determine which layers in my project might have a missing data source, so that my code doesn't crash later and I can present the user with a message to fix the problem. But when I call Layer.ConnectionStatus I get a 'NullReference' exception. Which I guess makes sense, since the layer is missing the data source. Am I just not using the ConnectionStatus properly??
foreach (Layer layer in map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
{
if (layer.ConnectionStatus == ConnectionStatus.Broken)
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("SOME KIND OF ERROR MESSSAGE");
}
Solved! Go to Solution.
Hi Brian,
That was a tricky issue to solve... as far as the loading sequence you can find information here: https://github.com/Esri/arcgis-pro-sdk/wiki/ProConcepts-Advanced-Topics#2-admin-well-known-folders Looking at this document i think the network share (in the registry) will trump everything else. Pro is using the following sequence: network path (registry) … user defined paths … and finally the default path for add-ins. The version tag in the config daml is actually only used to prevent an add-in from being loaded and run on an older version of Pro.
As far as the 'down cast' from FeatureLayer to BasicFeatureLayer, the only impact here is that FeatureLayers (you are getting FeatureLayers from the layer list) has more functionality (via properties and methods) than BasicFeatureLayer from which it is derived from.
Hi Brian,
I tried your code with FileGeodatabase as a datasource and the code worked fine after changed the folder name for the file GDB and restarted Pro. With what type of datasource were you seeing this issue?
Hi Wolfgang,
I am also using a FileGeodatabase.
When I debug it gets past the first layer, which is "Connected", but on the second layer (the one with the missing data source), I get the exception below thrown.
With mine, I am editing the name of the FeatureClass, not changing the folder name the FGDB sits in. Not sure if that would be the difference??
What build of Pro are you using? I just renamed just one of my feature classes, then I opened a project that had a map with a layer datasource still referencing the old name and it worked:
I am using 2.6.3
i tried it with 2.6.3 and it works fine. In my test i open the project and after the map is loaded i check the layers and none of them are null (i assume that the layer object in your code is null), even the one with the broken link. Are you processing the layer in some way before you run the 'broken' check ?
Hi Wolf,
No, there is nowhere in my code where I am doing anything with the object. I have been messing around, checking for the broken layer in different way, but I always get a NullReference error.
Since I also need to check for joined tablets, I am using the BasicFeatureLayer object which also uses .ConnectionStatus, but still the same problem.
Can you post your code you are using and I will try that?? Here is mine below, all running in a QueuedTask. The error happens right at the start of the first If statement.
foreach (Layer layer in map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
{
var currentLayer = map.FindLayers(layer.Name).FirstOrDefault() as BasicFeatureLayer;
if (currentLayer.ConnectionStatus == ConnectionStatus.Broken)
{ //THE ERROR HAPPENS HERE!!!!!
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(currentLayer.Name.ToString() + " has a missing data source. Please remove or fix this layer before continuing.", "Missing Data Source");
return;
}
if ((currentLayer.GetTable().IsJoinedTable() == true) && (currentLayer.SelectionCount > 0))
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(currentLayer.Name.ToString() + " has a joined table. Please remove any joins before continuing.", "Joined table detected");
joinExists = true;
}
}
In Debug mode it seems like the values are getting read properly, yet I still get the NullReference exception.
Hi Brian,
Below is my test code. I am not running within QueuedTask.Run, but i will try that shortly. Strangely enough i got the exception once as well, but i was not able to duplicate the error after that. i am still investigating that issue. The code snippet is taken from the OnClick of a button i added to my test add-in.
protected override void OnClick()
{
try
{
var map = MapView.Active.Map;
foreach (Layer layer in map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
{
//var currentLayer = map.FindLayers(layer.Name).FirstOrDefault() as BasicFeatureLayer;
var currentLayer = layer as BasicFeatureLayer;
System.Diagnostics.Debug.WriteLine($@"Name: {currentLayer.Name} Type: {currentLayer.GetType()} Connect status: {currentLayer.ConnectionStatus}");
}
}
catch (Exception ex)
{
MessageBox.Show($@"Exception: {ex}");
}
}
Hi Wolf,
When using your code, on a button with only that code on it, it works as expected and I see the 'Broken' status in the debug window.
If I take your code and plug it into mine, which is also the click event of a button, I still get the NullReference error. I'll paste all of my code below, but it must be something in my code that is the problem....I'm just not really sure what, or why.
There's a fair bit going on here, but I've tried to highlight (******) where the issues are.....just in the OnClick() portion as far as I can tell.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Collections;
using System.Windows.Input;
namespace ArcPro_DSM_Settings
{
internal class FacilityID_Button : Button
{
FeatureLayer localMunicipalityLayer;
string gridNumber, structureType;
int sequenceNumber;
string settlementArea, vlsFolder;
protected override void OnClick()
{
Map map = MapView.Active.Map;
//******* where I have inserted your code
foreach (Layer layer in map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
{
//var currentLayer = map.FindLayers(layer.Name).FirstOrDefault() as BasicFeatureLayer;
var currentLayer = layer as BasicFeatureLayer;
System.Diagnostics.Debug.WriteLine($@"Name: {currentLayer.Name} Type: {currentLayer.GetType()} Connect status: {currentLayer.ConnectionStatus}");
}
return;
int featureCount = 0;
int rejectedCount = 0;
Cursor theCursor = Cursors.Wait;
try
{
QueuedTask.Run(() =>
{
//Get each layer that needs to be part of the intersection as a FeatureLayer
FeatureLayer gridLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.Equals("GISWRKS1.WORKS.LAND_Grid", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
localMunicipalityLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.Equals("GISWRKS1.WORKS.LAND_LocalMunicipality", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
FeatureLayer administrativeAreaLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.Equals("GISWRKS1.WORKS.LAND_AdministrativeArea", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
FeatureLayer communitiesLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.Equals("GISWRKS1.WORKS.LAND_Communities", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
FeatureLayer depotAreaLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.Equals("GISWRKS1.WORKS.LAND_DepotArea", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
FeatureLayer pressureZoneLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.Equals("GISWRKS1.WORKS.WAT_PressureZone", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
FeatureLayer vlsLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.Equals("GISWRKS1.WORKS.VLS_Points", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
//Check to make sure they are all in the map
if (gridLayer == null || localMunicipalityLayer == null || administrativeAreaLayer == null || communitiesLayer == null || depotAreaLayer == null || pressureZoneLayer == null)
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Please add the LAND and Water Pressure Zone layers before proceeding.", "Missing Layers");
return;
}
//Create the MAIN edit operation...this will show up on the Undo Stack
var editOperation = new ArcGIS.Desktop.Editing.EditOperation();
editOperation.Name = "Create new Facility IDs";
editOperation.ProgressMessage = "Calculating FacilityID's...";
editOperation.ShowProgressor = true;
editOperation.CancelMessage = "Operation Cancelled";
editOperation.ErrorMessage = "Error Creating FacilityIDs";
editOperation.EditOperationType = ArcGIS.Desktop.Editing.EditOperationType.Long;
ArcGIS.Desktop.Editing.EditOperation chainedOp = null;
//create the Inspector Object
var inspector = new ArcGIS.Desktop.Editing.Attributes.Inspector();
//create a flag to track the 'main' operation
bool isMainOperation = true;
//Check for any Joins on layers with a selected feature
Boolean joinExists = false;
Boolean brokenExists = false;
foreach (Layer layer in map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
{
var currentLayer = map.FindLayers(layer.Name).FirstOrDefault() as BasicFeatureLayer;
//***** where my original code get the NullReference exception
if (currentLayer.ConnectionStatus == ConnectionStatus.Broken)
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(currentLayer.Name.ToString() + " has a missing data source. Please remove or fix this layer before continuing.", "Missing Data Source");
brokenExists = true;
}
if ((currentLayer.GetTable().IsJoinedTable() == true) && (currentLayer.SelectionCount > 0))
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(currentLayer.Name.ToString() + " has a joined table. Please remove any joins before continuing.", "Joined table detected");
joinExists = true;
}
}
if (joinExists || brokenExists)
return;
//Go through each layer in the map
foreach (Layer layer in map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
{
var currentLayer = map.FindLayers(layer.Name).FirstOrDefault() as BasicFeatureLayer;
//Does current layer have FACILITYID field??
Boolean facID_field = false;
facID_field = currentLayer.GetFieldDescriptions().Any(f => f.Name == "FACILITYID");
#region FACILITYID using FieldDescription
//Does current layer have FACILITYID field??
//Boolean facID_field = false;
//List<FieldDescription> theFields = currentLayer.GetFieldDescriptions();
//foreach (var fieldName in theFields)
//{
// if (fieldName.Name.ToString() == "FACILITYID")
// facID_field = true;
//}
#endregion
//if the FACILITYID field exists AND there is a selection, then continue....otherwise, look at next layer
if (currentLayer.SelectionCount > 0 && facID_field == true)
{
var selection = currentLayer.GetSelection();
IReadOnlyList<long> selectedOIDs = selection.GetObjectIDs(); //save the selected OBJECTIDs to a list.
structureType = GetFeatureClassCode(currentLayer);
//Loop through each selected OBJECTID, and pass the DRAWING and FACILITYID fields to the OpenDrawing method.
foreach (var oid in selectedOIDs)
{
inspector.Clear();
inspector.Load(currentLayer, oid);
MapPoint intersectPoint = null;
if (inspector["FACILITYID"].ToString() == "")
{
//if (inspector.GeometryAttribute.GeometryType == GeometryType.Polyline || inspector.GeometryAttribute.GeometryType == GeometryType.Polygon) //for polyline
//{
// var pointCollection = ((Multipart)inspector.Shape).Points;
// intersectPoint = pointCollection[0];
//}
//else
//{
// intersectPoint = inspector.Shape as MapPoint; //for point
//}
intersectPoint = GeometryEngine.Instance.Centroid(inspector.Shape);
//Make some of the initial edits
inspector["GRIDNO"] = GetIntersectingField(intersectPoint, "GRIDNO", gridLayer);
inspector["LOCALMUNICIPALITY"] = GetIntersectingField(intersectPoint, "LOCALMUNICIPALITY", localMunicipalityLayer);
inspector["SETTLEMENTAREA"] = GetIntersectingField(intersectPoint, "NAME", communitiesLayer);
inspector["DEPOTAREA"] = GetIntersectingField(intersectPoint, "DEPOTAREA", depotAreaLayer);
//Need to pass a FeatureCLass to the GetNextFaciltyID procedure
FeatureLayer currFLayer = currentLayer as FeatureLayer;
FeatureClass currFClass = currFLayer.GetFeatureClass();
//This is where the sequence number will get incremented each time (in the GetNextFacilityID)
inspector["FACILITYID"] = GetNextFacilityID(currFClass, gridNumber);
inspector["SEQUENCENO"] = sequenceNumber;
//make some more edits
inspector["STRUCTURETYPE"] = structureType;
if (Properties.Settings.Default.facIDContractNumberSetting == true)
inspector["CONTRACTNO"] = GetIntersectingField(intersectPoint, "CONTRACTNO", administrativeAreaLayer);
//Some more edits based on the current layer
if ((currentLayer.Name == "GISWRKS1.WORKS.SAN_Eff_Watermain") || (currentLayer.Name == "GISWRKS1.WORKS.SAN_Eff_WaterService") || (currentLayer.Name == "GISWRKS1.WORKS.SAN_Eff_Fitting") || (currentLayer.Name == "GISWRKS1.WORKS.SAN_Eff_ControlValve") || (currentLayer.Name == "GISWRKS1.WORKS.SAN_Eff_Hydrant"))
inspector["WATERTYPE"] = "NONPOT";
if (currentLayer.Name == "GISWRKS1.WORKS.SAN_Eff_Hydrant")
inspector["SUBTYPECD"] = 3;
if (currentLayer.Name == "GISWRKS1.WORKS.WAT_ControlValve")
inspector["PRESSUREZONE"] = GetIntersectingField(intersectPoint, "WPZ", pressureZoneLayer);
#region Code for VLS Points
if (currentLayer.Name == "GISWRKS1.WORKS.VLS_Points")
{
//Need to get the layer as a FeatureClass to do stats
FeatureClass vlsFC = vlsLayer.GetFeatureClass();
FeatureClassDefinition fcd = vlsFC.GetDefinition();
//Setup the the fields and Statistics Description
Field fldVLS_NO_1 = fcd.GetFields().First(x => x.Name.Equals("VLS_NO_1"));
StatisticsDescription vlsMaxDesc = new StatisticsDescription(fldVLS_NO_1, new List<StatisticsFunction>() { StatisticsFunction.Max });
TableStatisticsDescription tsd = new TableStatisticsDescription(new List<StatisticsDescription>() { vlsMaxDesc });
IReadOnlyList<TableStatisticsResult> vlsStatsResult = vlsFC.CalculateStatistics(tsd);
//Get the stat you are looking for
int vlsMax = (int)vlsStatsResult.First().StatisticsResults.First().Max + 1;
//Edit fields in the VLS with the new #
inspector["VLS_NO_1"] = vlsMax;
inspector["VLS_NO"] = vlsMax.ToString();
switch (inspector["SETTLEMENTAREA"].ToString())
{
case "AJAX":
settlementArea = "AJA";
vlsFolder = "AJAX";
break;
case "BLACKSTOCK":
settlementArea = "BKSTK";
vlsFolder = "CLARINGTON";
break;
case "BEAVERTON":
settlementArea = "BROBE";
vlsFolder = "BROCK";
break;
case "CANNINGTON":
settlementArea = "BROCA";
vlsFolder = "BROCK";
break;
case "SUNDERLAND":
settlementArea = "BROSL";
vlsFolder = "BROCK";
break;
case "BOWMANVILLE":
settlementArea = "CLB";
vlsFolder = "CLARINGTON";
break;
case "COURTICE":
settlementArea = "NEWCT";
vlsFolder = "CLARINGTON";
break;
case "NEWCASTLE":
settlementArea = "NEWNE";
vlsFolder = "CLARINGTON";
break;
case "ORONO":
settlementArea = "NEWOR";
vlsFolder = "CLARINGTON";
break;
case "NEWTONVILLE":
settlementArea = "NEWTON";
vlsFolder = "CLARINGTON";
break;
case "OSHAWA":
settlementArea = "OSH";
vlsFolder = "OSHAWA";
break;
case "PICKERING":
settlementArea = "PIC";
vlsFolder = "PICKERING";
break;
case "SCUGOG":
settlementArea = "SCU";
vlsFolder = "SCUGOG";
break;
case "GREENBANK":
settlementArea = "SCUGB";
vlsFolder = "SCUGOG";
break;
case "PORT PERRY":
settlementArea = "SCUPP";
vlsFolder = "SCUGOG";
break;
case "UXBRIDGE":
settlementArea = "UXB";
vlsFolder = "UXBRIDGE";
break;
case "UXVILLE":
settlementArea = "UXB";
vlsFolder = "UXBRIDGE";
break;
case "WHITBY":
settlementArea = "WHI";
vlsFolder = "WHITBY";
break;
case "BROOKLIN":
settlementArea = "WHIBR";
vlsFolder = "WHITBY";
break;
case "SEATON":
settlementArea = "PICSEA";
vlsFolder = "PICKERING";
break;
default:
settlementArea = "ERROR";
break;
}
inspector["FILENAME"] = settlementArea + vlsMax.ToString() + ".pdf";
inspector["COMMENTS"] = @"G:\OPERATIO\Data Systems Management\Valve Location System\PDF\" + vlsFolder + @"\" + settlementArea + vlsMax.ToString() + ".pdf";
inspector["DWGMXD"] = @"http://cctvweb/cctv/VLS/PDF/" + vlsFolder + @"\" + settlementArea + vlsMax.ToString() + ".pdf";
}
#endregion
if (isMainOperation)
{
editOperation.Modify(inspector);
bool result = editOperation.Execute();
//change the flag so we use the ChainedOp next
isMainOperation = false;
}
else
{
chainedOp = editOperation.CreateChainedOperation();
//queue up a Modify
chainedOp.Modify(inspector);
chainedOp.Execute();
}
//Increase the feature count for the final tally
featureCount++;
}
else
{
rejectedCount++;
}
} //go to next selected feature in current layer
} //end of if (currentLayer.SelectionCount > 0 && facID_field == true)
} //Go to the next layer in the map
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(featureCount.ToString() + " FacilityID's created. " + rejectedCount + " features already had FacilityID's.", "Process Complete");
}); //end of QueuedTask
}
catch (Exception ex)
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.ToString());
}
finally
{
}
}
//This does a SpatialQuery using the current feature point and a layer to get the intersecting field value
public string GetIntersectingField(MapPoint point, string fieldName, FeatureLayer sourceLayer)
{
try
{
SpatialQueryFilter spatialFilter = new SpatialQueryFilter();
spatialFilter.FilterGeometry = point;
spatialFilter.SpatialRelationship = SpatialRelationship.Intersects;
spatialFilter.SubFields = fieldName;
string fieldValue = "";
int i = 0;
RowCursor gridCursor = sourceLayer.Search(spatialFilter);
Feature feature;
while (gridCursor.MoveNext())
{
using (feature = (Feature)gridCursor.Current)
{
int fieldPosition = feature.FindField(fieldName);
fieldValue = feature[fieldPosition].ToString();
i++;
}
}
//if CONTRACTNO and more than one intersecting boundary, then show a message box and populate field with nothing
if ((fieldName == "CONTRACTNO") && (i > 1))
{
fieldValue = null;
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("There is more than one intersecting Contract Boundary for ??. Please enter this field in manually.", "Contract Number");
}
//if fieldName = NAME and it is blank, then find the SettlementArea by looking at the LocalMunicipality layer
if ((fieldName == "NAME") && (fieldValue == ""))
fieldValue = GetIntersectingField(point, "LOCALMUNICIPALITY", localMunicipalityLayer);
//set the gridNumber so we can use it again when we create the FACILITYID
if (fieldName == "GRIDNO")
gridNumber = fieldValue;
return fieldValue;
}
catch (Exception ex)
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.ToString());
return null;
}
}
//This will return the next FacilityID
public string GetNextFacilityID(FeatureClass fClass, string gridNum)
{
try
{
QueryFilter queryFilter = new QueryFilter();
queryFilter.WhereClause = "GRIDNO ='" + gridNum + "'";
queryFilter.SubFields = "SEQUENCENO";
//create an array to hold all of the SEQUENCENO; give it's first member the value zero
ArrayList idList = new ArrayList();
idList.Add(int.Parse("0"));
RowCursor rCursor = fClass.Search(queryFilter);
Feature feature;
while (rCursor.MoveNext())
{
using (feature = (Feature)rCursor.Current)
{
int sequencePosition = feature.FindField("SEQUENCENO");
idList.Add(Convert.ToInt32(feature[sequencePosition]));
}
}
//sort the list so we can get the highest value of SEQUENCENO
idList.Sort();
//the next # we want is the current highest number + 1
int number = (int)idList[idList.Count - 1] + 1;
sequenceNumber = number;
//convert it to a string so we can add the zero placeholders to the front of it....it needs to be 4 digits.
string finalNum = number.ToString();
switch (finalNum.Length)
{
case 1:
finalNum = "000" + finalNum;
break;
case 2:
finalNum = "00" + finalNum;
break;
case 3:
finalNum = "0" + finalNum;
break;
}
//return the full facility id, with the STRUCTURETYPE, GRIDNO, and SEQUENCENO
return structureType + "-" + gridNumber + "-" + finalNum;
}
catch (Exception ex)
{
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.ToString());
return null;
}
}
//This will return the StructureTypeCode for a layer
public string GetFeatureClassCode(Layer layer)
{
switch (layer.Name)
{
case "GISWRKS1.WORKS.SAN_Chamber":
return "SCH";
case "GISWRKS1.WORKS.SAN_Fitting":
return "SFT";
case "GISWRKS1.WORKS.SAN_Manhole":
return "MH";
case "GISWRKS1.WORKS.SAN_ControlValve":
return "SCV";
case "GISWRKS1.WORKS.SAN_ReliefValve":
return "SRV";
case "GISWRKS1.WORKS.SAN_InletOutletStructure":
return "IO";
case "GISWRKS1.WORKS.SAN_WWTFacility":
return "WTP";
case "GISWRKS1.WORKS.SAN_WWTFeature":
return "WWTF";
case "GISWRKS1.WORKS.SAN_PumpingStation":
return "SPS";
case "GISWRKS1.WORKS.SAN_Cleanout":
return "SCO";
case "GISWRKS1.WORKS.SAN_ServicePoint":
return "SPS"; //SAME AS SAN_PUMPINGSTATION
case "GISWRKS1.WORKS.SAN_SystemMeter":
return "SMTR"; //MISSING CODE IN GISWRKS1.WORKS.STRUCTTYPECODE
case "GISWRKS1.WORKS.ForceMain":
return "FM";
case "GISWRKS1.WORKS.GravitySewer":
return "SL";
case "GISWRKS1.WORKS.SAN_SewerService":
return "SSL";
case "GISWRKS1.WORKS.VLS_Points":
return "VLS";
case "GISWRKS1.WORKS.WAT_SystemMeter":
return "MTR";
case "GISWRKS1.WORKS.WAT_ServicePoint":
return "SP";
case "GISWRKS1.WORKS.WaterSupplyFacility":
return "WSP";
case "GISWRKS1.WORKS.WAT_PumpingStation":
return "WPS";
case "GISWRKS1.WORKS.WAT_TestStation":
return "TST";
case "GISWRKS1.WORKS.WAT_ControlValve":
return "WCV";
case "GISWRKS1.WORKS.WAT_ReliefValve":
return "WRV";
case "GISWRKS1.WORKS.WAT_Hydrant":
return "HYD";
case "GISWRKS1.WORKS.WAT_Fitting":
return "WFT";
case "GISWRKS1.WORKS.WaterMain":
return "WM";
case "GISWRKS1.WORKS.WaterService":
return "WSL";
case "GISWRKS1.WORKS.WAT_StorageFacility":
return "WST";
case "GISWRKS1.WORKS.WAT_Feature":
return "WF";
case "GISWRKS1.WORKS.WAT_Drainpipe":
return "DRNP";
case "GISWRKS1.WORKS.WAT_BulkFillingStation":
return "BFS";
case "GISWRKS1.WORKS.ssCleanOut":
return "STCO";
case "GISWRKS1.WORKS.ssLateralPoint":
return "LP";
case "GISWRKS1.WORKS.ssSystemValve":
return "SV";
case "GISWRKS1.WORKS.ssControlValve":
return "CV";
case "GISWRKS1.WORKS.ssMeter":
return "ME";
case "GISWRKS1.WORKS.ssPump":
return "PMP";
case "GISWRKS1.WORKS.ssCatchBasin":
return "SCB";
case "GISWRKS1.WORKS.ssFitting":
return "SSFT";
case "GISWRKS1.WORKS.ssMaintenanceHole":
return "STMH";
case "GISWRKS1.WORKS.ssInletOutlet":
return "SIO";
case "GISWRKS1.WORKS.ssLateralLine":
return "SLL";
case "GISWRKS1.WORKS.ssPressurizedMain":
return "SPM";
case "GISWRKS1.WORKS.ssGravityMain":
return "STM";
case "GISWRKS1.WORKS.Clearwell":
return "CW";
case "GISWRKS1.WORKS.Pump":
return "PU";
case "GISWRKS1.WORKS.ssStormNetworkStructure":
return "SNS";
case "GISWRKS1.WORKS.ssStormService":
return "SSL";
case "GISWRKS1.WORKS.SAN_Eff_ControlValve":
return "EFCV";
case "GISWRKS1.WORKS.SAN_Eff_Fitting":
return "EFFT";
case "GISWRKS1.WORKS.SAN_Eff_Hydrant":
return "EFHYD";
case "GISWRKS1.WORKS.SAN_Eff_Watermain":
return "EFWM";
case "GISWRKS1.WORKS.SAN_Eff_WaterService":
return "EFWSL";
case "GISWRKS1.WORKS.TBM_Chamber":
return "TBM";
case "GISWRKS1.WORKS.TBM_Chamber_poly":
return "TBM";
default:
return null;
}
}
}
}
.