Changing the order of multipart Geometries - arcobjects

I have a group of Multipart Polyline Geometries which have measures. I am trying to re-order the geometries to better follow the traffic flow.
I am using a GeometryBridge to add the re-orderd segments to an ISegmentCollection.
The problem is that my segments have their M values reset so they must be IMSegmentation4 segments. When I try to add these to an ISegmentCollection VS the program won't compile.
I am using VS2010, ArcGis 10.2 and Windows 7.
pExGeomColl = (IGeometryCollection)new Polyline();
pExGeomColl = (IGeometryCollection)pBaseFeat.ShapeCopy;
for (int i = 0; i < hGeomToFrom.Count; i++)
{
iTo = i;
iFrom = (int)hGeomToFrom[i];
pGeom = pExGeomColl.Geometry[iFrom];
pGeom.SpatialReference = pSpRef;
pMAware = (IMAware)pGeom;
pMAware.MAware = true;
pPolyline = (IPolyline6)new PolylineClass();
if (pGeom.GeometryType != esriGeometryType.esriGeometryPolyline)
{
pPolyline = geometryToPolyline(pGeom, false, true, ref sError);
if (sError.Length > 0)
{
sError = "cmdReset\r\n" + sError;
clsMain.write_log(sError, clsMain.m_eLogType.FATAL);
MessageBox.Show(sError);
return;
}
}
else
{
pPolyline = (IPolyline)pGeom;
}
dLen = pPolyline.Length;
dFrom = dMeasure;
dTo = dFrom + dLen;
pSeg = (IMSegmentation4)pPolyline;
pSeg.SetAndInterpolateMsBetween(dFrom, dTo);
dMeasure = dTo;
pSegArray[i] = pSeg;
ProgressBar1.Value = iCount;
iCount++;
}
// Add the segment array to a segment collection
pNewSegColl = (ISegmentCollection)new PolylineClass();
pMAware = (IMAware)pNewSegColl;
pMAware.MAware = true;
pGeomBridge = new GeometryEnvironmentClass();
pGeomBridge.AddSegments(pNewSegColl, pSegArray); // This doesn't work
pGeom = (IGeometry)pNewSegColl;
pGeom.SpatialReference = pSpRef;
pBaseFeat.Shape = pGeom;
pBaseFeat.Store();
Can anyone tell me how to accumulate a set of measure segments?

I found that using a Segment Collection is the wrong approach. A segment is the line segment between vertices of a polyline.
The trick is to put the polyline into a geometry collection and then add the parts of that geometry collection into the new (re-ordered) collection.
// Existing Geometry Collection
pExGeomColl = (IGeometryCollection)new PolylineClass();
pExGeomColl = (IGeometryCollection)pBaseFeat.ShapeCopy;
// New Geometry collection
pNewGeomColl = (IGeometryCollection)new PolylineClass();
pMAware = (IMAware)pNewGeomColl;
pMAware.MAware = true;
pZAware = (IZAware)pNewGeomColl;
pZAware.ZAware = bHasZ;
for (int i = 0; i < hGeomToFrom.Count; i++)
{
iTo = i;
iFrom = (int)hGeomToFrom[i];
pGeom = pExGeomColl.Geometry[iFrom];
pGeom.SpatialReference = pSpRef;
pMAware = (IMAware)pGeom;
pMAware.MAware = true;
pZAware = (IZAware)pGeom;
pZAware.ZAware = bHasZ;
// Convert the geometry to a polyline
pPolyline = (IPolyline6)new PolylineClass();
if (pGeom.GeometryType != esriGeometryType.esriGeometryPolyline)
{
pPolyline = geometryToPolyline(pGeom, bHasZ, true, ref sError);
if (sError.Length > 0)
{
sError = "cmdReset\r\n" + sError;
clsMain.write_log(sError, clsMain.m_eLogType.FATAL);
MessageBox.Show(sError);
return;
}
}
else
{
pPolyline = (IPolyline)pGeom;
}
pMAware = (IMAware)pPolyline;
pMAware.MAware = true;
pZAware = (IZAware)pPolyline;
pZAware.ZAware = bHasZ;
dLen = pPolyline.Length;
dFrom = dMeasure;
dTo = dFrom + dLen;
pSeg = (IMSegmentation4)pPolyline;
pSeg.SetAndInterpolateMsBetween(dFrom, dTo);
IGeometryCollection pXGeomColl = new PolylineClass();
pMAware = (IMAware)pXGeomColl;
pMAware.MAware = true;
pZAware = (IZAware)pXGeomColl;
pZAware.ZAware = bHasZ;
pXGeomColl = (IGeometryCollection)pPolyline;
for (int j = 0; j < pXGeomColl.GeometryCount; j++)
pNewGeomColl.AddGeometry(pXGeomColl.Geometry[j]);
dMeasure = dTo;
ProgressBar1.Value = iCount;
iCount++;
}
pGeom = (IGeometry)pNewGeomColl;
pGeom.SpatialReference = pSpRef;
pMAware = (IMAware)pGeom;
pMAware.MAware = true;
pZAware = (IZAware)pGeom;
pZAware.ZAware = bHasZ;
pBaseFeat.Shape = pGeom;
pBaseFeat.Store();

Related

how to replace array object in flutter

if(_list.length != 0){
var shape;
var shapeCount;
var shapeCaratCount;
var shapeTotalAmount;
var details = new Map();
var temp = [Map()];
for(int l = 0 ; l <= _list.length; l++){
var list = _list[l];
if(temp.contains(list.shape)){
shapeCount += 1;
shapeCaratCount = shapeCaratCount + list.carat;
shapeTotalAmount = shapeTotalAmount + list.totalAmount;
details['Shape'] = list.shape;
details['pcs_count'] = shapeCount;
details['Carat_Count'] = shapeCaratCount;
details['total_amount'] = shapeTotalAmount;
print(details);
temp.add(details);
}else{
shapeCount = 0;
//shapeCaratCount = shapeCaratCount + list.carat;
shapeCaratCount = list.carat;
shapeTotalAmount = list.totalAmount;
details['Shape'] = list.shape;
details['pcs_count'] = shapeCount;
details['Carat_Count'] = shapeCaratCount.toString();
details['total_amount'] = shapeTotalAmount.toString();
print(details);
temp.add(details);
}
}
}
I want to replace array object of temp dictionary array.
so if any know how to do this please help i am new at flutter
this is my code please if any difficulty. please ask.

VSC Formatter Implementation no effect

Issue Type: Bug
Launch Extension
Right click Reformat file (.items file from openhab)
VS Code version: Code 1.47.0
OS version: Darwin x64 19.5.0
Hey guys,
With the following implementation nothing happens when saving the file (format on save enabled) or when reformatting the file with a right click. I tried a lot of other solutions but none of them worked. I hope you can help me.
export function activate(context: vscode.ExtensionContext) {
vscode.languages.registerDocumentFormattingEditProvider("openhab", {
provideDocumentFormattingEdits(document: vscode.TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
var range = getDocumentRange(document);
var content = document.getText(range);
var result: vscode.TextEdit[] = [];
var formatted = formatItemFile();
//if (formatted) {
// result.push(new vscode.TextEdit(range, formatted));
//}
return formatted;
},
});
}
export function formatItemFile(): vscode.TextEdit[] {
var result: vscode.TextEdit[] = [];
// Get the section lengths of each line with an item in it.
// Only execute if there's an active text editor
if (!vscode.window.activeTextEditor) {
return result;
}
// Define the basic vscode variables
let doc = vscode.window.activeTextEditor.document;
let editor = vscode.window.activeTextEditor;
let currentPos = editor.selection.active;
let newPos: vscode.Position;
let itemArray: Array<Item>;
itemArray = new Array();
// Get the format configuration settings
let config = vscode.workspace.getConfiguration("oh-alignment-tool");
let preserveWhitespace = config.preserveWhitespace;
// Reset the comment tracker
isInBlockComment = false;
// Clear the file in case of line-by-line item definitions
for (let index = 0; index < doc.lineCount; index++) {
// Get Position at the beginning of the current line and start a selection
newPos = currentPos.with(index, 0);
editor.selection = new vscode.Selection(newPos, newPos);
// Get Text of current line and check if there is a comment in it
let lineText = doc.lineAt(newPos.line);
var comment = doc.getWordRangeAtPosition(newPos.with(newPos.line, 0), REGEX_COMMENT);
var blockComment = doc.getWordRangeAtPosition(newPos.with(newPos.line, 0), REGEX_START_BLOCKCOMMENT);
var endBlockComment = doc.getWordRangeAtPosition(newPos.with(newPos.line, 0), REGEX_END_BLOCKCOMMENT);
// If line is empty or contains a comment continue to the next line
if (lineText.text.length === 0 || lineText.isEmptyOrWhitespace) {
continue;
} else if (comment) {
continue;
} else if (blockComment && endBlockComment) {
isInBlockComment = false;
continue;
} else if (blockComment) {
isInBlockComment = true;
continue;
} else if (endBlockComment) {
isInBlockComment = false;
continue;
} else if (isInBlockComment) {
continue;
}
// Default these to empty. They will be changed
// if they exist in the item definition
let itemType = "";
let itemName = "";
let itemLabel = "";
let itemIcon = "";
let itemGroup = "";
let itemTag = "";
let itemChannel = "";
let itemComment = "";
// Check if there is leading Whitespace. If Yes add one in size of a tab.
let leadingWhiteSpace = lineText.firstNonWhitespaceCharacterIndex;
if (preserveWhitespace === false) {
leadingWhiteSpace = 0;
}
// Discover item Type
// Count Whitespace or tabs at the begin of the line
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
var wordRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_TYPE);
if (wordRange && wordRange.isSingleLine) {
itemType = doc.getText(wordRange);
highestTypeLength = itemType.length > highestTypeLength ? itemType.length : highestTypeLength;
newPos = newPos.with(newPos.line, newPos.character + itemType.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
// Discover item Name
var itemNameRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_NAME);
if (itemNameRange && itemNameRange.isSingleLine) {
itemName = doc.getText(itemNameRange);
highestNameLength = itemName.length > highestNameLength ? itemName.length : highestNameLength;
newPos = newPos.with(newPos.line, newPos.character + itemName.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
}
// Must have a type and name to continue
if (itemType.length === 0 || itemName.length === 0) {
continue;
}
// Discover item Label
let itemLabelRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_LABEL);
if (itemLabelRange && itemLabelRange.isSingleLine) {
itemLabel = doc.getText(itemLabelRange);
highestLabelLength = itemLabel.length > highestLabelLength ? itemLabel.length : highestLabelLength;
newPos = newPos.with(newPos.line, newPos.character + itemLabel.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Icon
let itemIconRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_ICON);
if (itemIconRange && itemIconRange.isSingleLine) {
itemIcon = doc.getText(itemIconRange);
highestIconLength = itemIcon.length > highestIconLength ? itemIcon.length : highestIconLength;
newPos = newPos.with(newPos.line, newPos.character + itemIcon.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Group
let itemGroupRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_GROUP);
if (itemGroupRange && itemGroupRange.isSingleLine) {
itemGroup = doc.getText(itemGroupRange);
highestGroupLength = itemGroup.length > highestGroupLength ? itemGroup.length : highestGroupLength;
newPos = newPos.with(newPos.line, newPos.character + itemGroup.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Tag
let itemTagRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_TAG);
if (itemTagRange && itemTagRange.isSingleLine) {
itemTag = doc.getText(itemTagRange);
highestTagLength = itemTag.length > highestTagLength ? itemTag.length : highestTagLength;
//console.log("Tag: " + itemTag);
newPos = newPos.with(newPos.line, newPos.character + itemTag.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover item Channel
let itemChannelRange = doc.getWordRangeAtPosition(newPos, REGEX_ITEM_CHANNEL);
if (itemChannelRange && itemChannelRange.isSingleLine) {
itemChannel = doc.getText(itemChannelRange);
highestChannelLength = itemChannel.length > highestChannelLength ? itemChannel.length : highestChannelLength;
newPos = newPos.with(newPos.line, newPos.character + itemChannel.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Discover comment at end of line
let itemCommentRange = doc.getWordRangeAtPosition(newPos, REGEX_EOL_COMMENT);
if (itemCommentRange && itemCommentRange.isSingleLine) {
itemComment = doc.getText(itemCommentRange);
newPos = newPos.with(newPos.line, newPos.character + itemComment.length);
newPos = newPos.with(newPos.line, newPos.character + utils.countWhitespace(doc, newPos));
}
// Add the new item to the itemArray
itemArray.push(new Item(index, leadingWhiteSpace, itemType, itemName, itemLabel, itemIcon, itemGroup, itemTag, itemChannel, itemComment));
}
// Convert the column lengths to tabs
highestTypeLength = utils.generateTabFromSpaces(highestTypeLength);
highestNameLength = utils.generateTabFromSpaces(highestNameLength);
highestLabelLength = utils.generateTabFromSpaces(highestLabelLength);
highestIconLength = utils.generateTabFromSpaces(highestIconLength);
highestGroupLength = utils.generateTabFromSpaces(highestGroupLength);
highestTagLength = utils.generateTabFromSpaces(highestTagLength);
highestChannelLength = utils.generateTabFromSpaces(highestChannelLength);
// Insert the newly formatted items
itemArray.forEach(function (item) {
newPos = currentPos.with(item.line, 0);
editor.selection = new vscode.Selection(newPos, newPos);
let reformattedItem = formatItem(item);
if (reformattedItem !== "") {
let selection = new vscode.Range(newPos, newPos.with(newPos.line, doc.lineAt(newPos.line).text.length));
result.push(new vscode.TextEdit(selection, reformattedItem));
}
});
// Apply all clean and formatting Edits
//textWorkEdit.set(doc.uri, textTextEdits);
//await vscode.workspace.applyEdit(textWorkEdit);
return result;
}

VSCode language extension with hierarchical Outline, DocumentSymbol

I'm trying to get outline working with a custom language in VScode. I have the below code but I feel like it is slow because of the way I find a range in class. Are there better ways to find the range and assign children. I've thought about just keeping track of the depth of the brackets and assigning all functions/methods/classes in higher depths into the last item of previous depth.
It was based off of this answer.
class JSLDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(document: vscode.TextDocument,
token: vscode.CancellationToken): Thenable<vscode.DocumentSymbol[]> {
return new Promise((resolve, reject) => {
var symbols: vscode.DocumentSymbol[] = [];
var depth = 0;
for (var i = 0; i < document.lineCount; i++) {
var line = document.lineAt(i);
var txt = line.text;
var ltxt = txt.toLowerCase();
let open_brackets = ltxt.match(/\(/g) || [];
let close_brackets = ltxt.match(/\)/g) || [];
// console.log(ltxt)
// console.log(open_brackets, close_brackets)
//console.log(i, open_brackets.length, close_brackets.length)
depth += open_brackets.length - close_brackets.length;
//console.log(depth);
if (ltxt.includes("define class(")) {
let sname = txt.trim().substr(14, txt.trim().length - 16); //this is hard coded right now but it's kind of working
let detail = "ARGS:x, y returns z";
let start_pos = new vscode.Position(i, 0);
let n_bracket = 1;
let i_char = 0;
//let children: vscode.DocumentSymbol[] = []
let ds = new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Class, line.range, line.range);
for(var i_line = i; n_bracket > 0; i_line++){
let class_line = document.lineAt(i_line);
let mtxt = class_line.text;
let ic;
if(i == i_line) ic = 16;
else ic = 0;
for(i_char = ic; i_char < mtxt.length; i_char++){
if(mtxt[i_char] === "(") n_bracket++;
else if(mtxt[i_char] === ")") n_bracket--;
if(n_bracket === 0) break
}
if (/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i.test(mtxt)) {
let result = mtxt.match(/(\w[\w\d\s]*)=\s*method\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
let mname = result[1].trim();
let m_details = ""
if(result.length == 3){
m_details = result[2].trim();
}
ds.children.push(new vscode.DocumentSymbol(mname, m_details, vscode.SymbolKind.Method, class_line.range, class_line.range));
}
if(n_bracket === 0) break
}
let end_pos = new vscode.Position(i_line, i_char);
let rng = new vscode.Range(start_pos, end_pos);
ds.range = rng;
//ds.children = children;
symbols.push(ds);
}
else if (/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/.test(ltxt)) {
let result = txt.match(/(\w[\w\d\s]*)=\s*function\({((?:\s*(?:\w[\w\d\s]*)(?:=[^,]*)?,?\s*)*)},/i)!;
let sname = result[1].trim();
let detail = "";
if(result.length == 3){
detail = "(" + result[2].trim() + ")";
}
symbols.push(new vscode.DocumentSymbol(sname, detail, vscode.SymbolKind.Function, line.range, line.range));
}
}
resolve(symbols);
});
}
}

Arcobjects: set measures based on the polyline length

I am currently linear referencing a set of roads. Using IMSegmatation2.SetMsAsDistance2 works fine for single-part polylines but for multi-part polylines I want to set the M values as the length along the polyline to the point, not the shortest distance between the point and the start point of the polyline. The SetMsAsDistance2 function sets the Measures on parallel lines as equal. I want them to be different.
Apart from setting an M value for each polyline vertex does anyone know of a method that sets the M as the length along the polyline?
The solution is to use the IMSegmentation3.SetAndInterpolateMsBetween function.
Note that the solution assumes that the geometries that make up the feature are in the right order. It assigns measures geometry-by-geometry.
The code for this is:
public static void measuresAdd_NonDuplicating(ref IFeature pFeat, bool bHasZ, bool bIgnoreGaps, out string sError)
{
// Add non-duplicating measures to the feature
sError = "";
IMSegmentation3 pSeg;
IGeometryCollection pGeomColl;
//IGeometryCollection pNewGeomColl; // Use if geometries are to be re-ordered.
IGeometry pGeom;
IPolyline4 pPoly;
IQueryFilter pQ;
IMAware pMAware;
IZAware pZAware;
double dStartMeasure;
double dToMeasure;
double dMeasure;
double dLen;
try
{
if (pFeat.ShapeCopy.IsEmpty == false)
{
pGeomColl = (IGeometryCollection)new PolylineClass();
pGeomColl = (IGeometryCollection)pFeat.ShapeCopy;
if (pGeomColl.GeometryCount == 1)
{
// Single line geometry. Duplication not an issue.
pMAware = (IMAware)pFeat.ShapeCopy;
pMAware.MAware = true;
pSeg = (IMSegmentation3)pMAware;
pPoly = geometryToPolyline((IGeometry)pFeat.ShapeCopy, out sError);
if (sError.Length > 0)
{
sError = "measuresAdd_NonDuplicating\r\n" + sError;
return;
}
pSeg.SetMsAsDistance2(pPoly.FromPoint, 1, 0, bIgnoreGaps);
pFeat.Shape = (IGeometry)pSeg;
pFeat.Store();
}
else
{
// For re-ordering geometries. Not currently used.
//pNewGeomColl = (IGeometryCollection)new Polyline();
//IZAware pZawareNew = (IZAware)pNewGeomColl;
//pZawareNew.ZAware = bHasZ;
//IMAware pMAwareNew = (IMAware)pNewGeomColl;
//pMAwareNew.MAware = true;
dStartMeasure = 0;
dMeasure = 0;
// MultiGeometry. Place them in order and set the measures on each part increasing.
// Currently assumes the existing order is correct.
for (int i = 0; i < pGeomColl.GeometryCount; i++)
{
pGeom = pGeomColl.Geometry[i];
pPoly = geometryToPolyline(pGeom, out sError);
if (sError.Length > 0)
{
sError = "measuresAdd_NonDuplicating\r\n" + sError;
return;
}
// Measure Values
dStartMeasure = dMeasure;
if (i > 0) dStartMeasure += 0.01;
dLen = pPoly.Length;
dToMeasure = dMeasure + dLen;
// Set Measures
pMAware = (IMAware)pPoly;
pMAware.MAware = true;
pZAware = (IZAware)pPoly;
pZAware.ZAware = bHasZ;
pSeg = (IMSegmentation3)pPoly;
pSeg.SetAndInterpolateMsBetween(dStartMeasure, dToMeasure);
// If geometries are re-ordered into a connecting network
//IGeometryCollection pXGeomColl = new PolylineClass();
//pMAware = (IMAware)pXGeomColl;
//pMAware.MAware = true;
//pZAware = (IZAware)pXGeomColl;
//pZAware.ZAware = bHasZ;
//pXGeomColl = (IGeometryCollection)pPoly;
//for (int j = 0; j < pXGeomColl.GeometryCount; j++)
// pNewGeomColl.AddGeometry(pXGeomColl.Geometry[j]);
dMeasure += dLen;
}
pFeat.Shape = (IGeometry)pGeomColl;
}
}
}
catch (Exception ex)
{
System.Diagnostics.StackTrace pStack = new System.Diagnostics.StackTrace(ex, true);
System.Diagnostics.StackFrame pFrame = pStack.GetFrame(pStack.FrameCount - 1);
int iLineNo = pFrame.GetFileLineNumber();
sError = "ERROR: measuresAdd_NonDuplicating; Line: " + iLineNo + "\n" + ex.ToString();
}
}

IGeometryCollection of Polylines returns Paths

I have an file of points which are to be converted to a set of polylines. Some of the lines are multipart and I want to convert them to singlepart.
The points are processed and the polylines added to an Interim featureclass (for backup purposes). If a line is multipart it is added to this interim featureclass as multipart.
The interim featureclass is then read and it's features copied to a base featureclass. This works fine for single part features but I keep getting the 'No support for this geometry type' error when converting the multiparts to singleparts. The problem is that to create the multipart feature from a set of points I have to use a segment collection as a Path. I've tried setting this to a polyline but then adding line segments to it causes an error (wrong geometry type).
When I add the multipart features to the interim featureclass the geometries are Polylines. When I retrieve them later (by putting thte shape into a new GeometryCollection) the geometry collection is a Polyline but the individual geometries are Paths (?).
The code is:
1. Add points to interim featureclass by putting them in a pointcollection.
pPtColl = (IPointCollection4)new Polyline();
pGeomColl = (IGeometryCollection)new Polyline();
// Fill point collection
.......
// Create a path made up of segments from the point collection
ISegment pSegment;
ISegmentCollection pSegColl = (ISegmentCollection)new ESRI.ArcGIS.Geometry.Path(); // Fails if changed to new Polyline()
// M and Z aware
if (bHasZ == true)
{
pZAware = (IZAware)pSegColl;
pZAware.ZAware = true;
}
if (bHasM == true)
{
pMAware = (IMAware)pSegColl;
pMAware.MAware = true;
}
for (int n = 1; n < pPtColl.PointCount; n++)
{
pSegment = (ISegment)new Line();
pSegment.SpatialReference = pSpRef;
pSegment.FromPoint = pPtColl.Point[n - 1];
pSegment.ToPoint = pPtColl.Point[n];
pSegColl.AddSegment(pSegment, oMissing, oMissing);
}
pGeomColl.AddGeometry(pSegColl as IGeometry, oMissing, oMissing);
pGeom = (IGeometry)pGeomColl; // pGeom has geometry type = Polyline
pGeom.SpatialReference = pSpRef;
pFeat.Shape = pGeom;
This part of the code all works fine.
When processing these features from the interim featureclass to add them to the base featureclass I get an error because the geometry type from the geometry collection is 'Path' not 'Polyline'.
// Read the geometry from the interim feature into a geometry collection
pGeomColl = (IGeometryCollection)new Polyline();
pGeomColl = (IGeometryCollection)pFromFeature.ShapeCopy;
for (int j = 0; j < pGeomColl.GeometryCount; j++)
{
// Create a new (Polyline) feature pToFeat and populate its attributes
pToFeat = pToFC.CreateFeature();
....
// pGeomColl has geometry type = Polyline
pGeom = pGeomColl.Geometry[j]; // pGeom has geometry type = Path
pToFeat.Shape = pGeom; // Fails. pToFeat is a Polyline.
}
How can I ensure that the geometry collection contains geometries with Polylines rather than Paths?
Thanks,
JM
I have found what I condsider to be a workaround for this problem but it's not very pretty.
The solution is to cast the Path geometry into a polyline and then cast it back into a geometry when assigning it to the .Shape attribute.
if (pToFeat .ShapeCopy.GeometryType == esriGeometryType.esriGeometryPolyline && pGeom.GeometryType == esriGeometryType.esriGeometryPath)
{
IPolyline pPoly = (IPolyline)new Polyline();
pPoly = geometryToPolyline(pGeom, bHasZ, bHasM, ref sError);
if (sError.Length > 0)
{
sError = "processAdds; ID = " + sID + " OID = " + iOID.ToString() + sNL + sError;
clsMain.write_log(sError, clsMain.m_eLogType.FATAL);
iErrorCount++;
}
else
{
pToFeat.Shape = (IGeometry)pPoly;
}
}
private static IPolyline geometryToPolyline(IGeometry pInputGeom, bool bHasZ, bool bHasM, ref string sError)
{
IPolyline pPoly = null;
IGeometryCollection pPolyColl = null;
IZAware pZAware;
IMAware pMAware;
double dZ;
ISpatialReference pSpRef;
bool bIsMulti;
esriGeometryType pType;
try
{
sError = "";
pSpRef = pInputGeom.SpatialReference;
// Create a new polyline
pPoly = (IPolyline)new Polyline();
if (bHasZ == true)
{
pZAware = (IZAware)pPoly;
pZAware.ZAware = true;
}
if (bHasM == true)
{
pMAware = (IMAware)pPoly;
pMAware.MAware = true;
}
// Create the geometry collection
pPolyColl = (IGeometryCollection)new Polyline();
if (bHasZ == true)
{
pZAware = (IZAware)pPolyColl;
pZAware.ZAware = true;
}
if (bHasM == true)
{
pMAware = (IMAware)pPolyColl;
pMAware.MAware = true;
}
// Set the polyline as the geometry collection
pPoly = (IPolyline)pPolyColl;
pPoly.SpatialReference = pSpRef;
pPolyColl.AddGeometry(pInputGeom);
return pPoly;
}
catch (Exception ex)
{
System.Diagnostics.StackTrace pStack = new System.Diagnostics.StackTrace(ex, true);
System.Diagnostics.StackFrame pFrame = pStack.GetFrame(pStack.FrameCount - 1);
int iLineNo = pFrame.GetFileLineNumber();
sError = "ERROR: geometryToPolyline; Line: " + iLineNo + "\n" + ex.ToString();
return pPoly;
}
}