string TextObjectImp::getSubstitutedText() { string txt = getText(); DataElement* pParent = getElement(); pParent = (pParent == NULL) ? NULL : pParent->getParent(); DataDescriptor* pParentDesc = (pParent == NULL) ? NULL : pParent->getDataDescriptor(); DynamicObject* pParentMetadata = (pParentDesc == NULL) ? NULL : pParentDesc->getMetadata(); for (int i = 0; i < 50; ++i) { //each pass does replacement of $M(a) currently in the string. //do 50 passes to perform sub-expansion at most fifty times, ie. prevent infinite loop //for non-terminating recursive expansion string::size_type pos = txt.find("$"); while (pos != string::npos) { if (pos + 1 >= txt.size()) { break; } string type = txt.substr(pos+1, 1); if (type != "$") //ie. not $$, the escape sequence so continue { bool replaced = false; if (pos+4 < txt.size()) //ie. $M(a) { if (txt[pos+2] == '(') { string::size_type closeParen = txt.find(')', pos+2); if (closeParen == string::npos) { closeParen = txt.size(); } string variableName = txt.substr(pos+3, closeParen-(pos+2)-1); string replacementString; if (type == "M" || type == "S") { DataElement* pElmnt = pParent; DynamicObject* pMetadata = pParentMetadata; if (variableName.substr(0, 2) == "//") { string::size_type endNamePos = variableName.find("//", 2); if (endNamePos != string::npos) { string elementName = variableName.substr(2, endNamePos - 2); variableName = variableName.substr(endNamePos + 2); if (!variableName.empty()) { if (elementName[0] == '[' && elementName[elementName.size() - 1] == ']') { elementName = elementName.substr(1, elementName.size() - 2); std::list<GraphicObject*> objects; getLayer()->getObjects(VIEW_OBJECT, objects); for (std::list<GraphicObject*>::iterator object = objects.begin(); object != objects.end(); ++object) { GraphicObject* pObj = *object; if (pObj->getName() == elementName) { SpatialDataView* pSdv = dynamic_cast<SpatialDataView*>(pObj->getObjectView()); if (pSdv != NULL) { pElmnt = pSdv->getLayerList()->getPrimaryRasterElement(); DataDescriptor* pDesc = (pElmnt == NULL) ? NULL : pElmnt->getDataDescriptor(); pMetadata = (pDesc == NULL) ? NULL : pDesc->getMetadata(); } break; } } } else { pElmnt = Service<ModelServices>()->getElement(elementName, TypeConverter::toString<RasterElement>(), NULL); DataDescriptor* pDesc = (pElmnt == NULL) ? NULL : pElmnt->getDataDescriptor(); pMetadata = (pDesc == NULL) ? NULL : pDesc->getMetadata(); } } else { pElmnt = NULL; pMetadata = NULL; } } } bool success = false; if (type == "M" && pMetadata != NULL) { DataVariant var = pMetadata->getAttributeByPath(variableName); if (var.isValid()) { DataVariant::Status status; replacementString = var.toDisplayString(&status); success = (status == DataVariant::SUCCESS); if (mMetadataObjects.find(pMetadata) == mMetadataObjects.end()) { mMetadataObjects.insert(make_pair(pMetadata, new AttachmentPtr<DynamicObject>( pMetadata, SIGNAL_NAME(Subject, Modified), Slot(this, &TextObjectImp::invalidateTexture)))); } } } else if (type == "S" && pElmnt != NULL && variableName == "CLASSIFICATION") { Classification* pClass = pElmnt->getDataDescriptor()->getClassification(); pClass->getClassificationText(replacementString); success = true; if (mClassificationObjects.find(pClass) == mClassificationObjects.end()) { mClassificationObjects.insert(make_pair(pClass, new AttachmentPtr<Classification>( pClass, SIGNAL_NAME(Subject, Modified), Slot(this, &TextObjectImp::invalidateTexture)))); } } if (!success) { replacementString = "Error!"; } replaced = true; } if (replaced) { txt.replace(pos, closeParen-pos+1, replacementString); pos = txt.find("$", pos+replacementString.size()); } } } if (!replaced) { pos = txt.find("$", pos+1); } } else { pos = txt.find("$", pos+2); } } } string::size_type pos = txt.find("$$"); while (pos != string::npos) { txt.replace(pos, 2, "$"); pos = txt.find("$$"); } return txt; }
void Kml::generatePolygonalLayer(const GraphicLayer* pGraphicLayer, bool visible, int order, const Layer* pGeoLayer) { VERIFYNRV(pGeoLayer != NULL); if (pGraphicLayer == NULL) { return; } RasterElement* pGeoElement = dynamic_cast<RasterElement*>(pGeoLayer->getDataElement()); mXml.pushAddPoint(mXml.addElement("Folder")); string name = pGraphicLayer->getDisplayName(); if (name.empty()) { name = pGraphicLayer->getName(); } mXml.addText(name, mXml.addElement("name")); mXml.addText(pGraphicLayer->getDisplayText(), mXml.addElement("description")); mXml.addText(visible ? "1" : "0", mXml.addElement("visibility")); list<GraphicObject*> objects; pGraphicLayer->getObjects(objects); for (list<GraphicObject*>::const_iterator object = objects.begin(); object != objects.end(); ++object) { GraphicObject* pObject = *object; if (pObject == NULL) { continue; } mXml.pushAddPoint(mXml.addElement("Placemark")); mXml.addText(pObject->getName(), mXml.addElement("name")); mXml.addText(pObject->isVisible() ? "1" : "0", mXml.addElement("visibility")); mXml.pushAddPoint(mXml.addElement("Style")); mXml.pushAddPoint(mXml.addElement("PolyStyle")); ColorType c = pObject->getFillColor(); QChar fc('0'); mXml.addText(QString("%1%2%3%4").arg(c.mAlpha, 2, 16, fc).arg(c.mBlue, 2, 16, fc).arg( c.mGreen, 2, 16, fc).arg(c.mRed, 2, 16, fc).toAscii().data(), mXml.addElement("color")); mXml.addText(pObject->getLineState() ? "1" : "0", mXml.addElement("outline")); mXml.addText(pObject->getFillState() ? "1" : "0", mXml.addElement("fill")); mXml.popAddPoint(); // PolyStyle mXml.pushAddPoint(mXml.addElement("LineStyle")); c = pObject->getLineColor(); mXml.addText(QString("%1%2%3%4").arg(c.mAlpha, 2, 16, fc).arg(c.mBlue, 2, 16, fc).arg( c.mGreen, 2, 16, fc).arg(c.mRed, 2, 16, fc).toAscii().data(), mXml.addElement("color")); mXml.addText(StringUtilities::toXmlString(pObject->getLineWidth()), mXml.addElement("width")); mXml.popAddPoint(); // LineStyle mXml.popAddPoint(); // Style switch (pObject->getGraphicObjectType()) { case MULTIPOINT_OBJECT: { mXml.pushAddPoint(mXml.addElement("MultiGeometry")); vector<LocationType> vertices = static_cast<MultipointObject*>(pObject)->getVertices(); for (vector<LocationType>::const_iterator vertex = vertices.begin(); vertex != vertices.end(); ++vertex) { mXml.pushAddPoint(mXml.addElement("Point")); mXml.addText(QString::number(order).toAscii().data(), mXml.addElement("drawOrder")); LocationType geo = pGeoElement->convertPixelToGeocoord(*vertex); mXml.addText(QString("%1,%2").arg(geo.mY, 0, 'f', 10).arg(geo.mX, 0, 'f', 10).toAscii().data(), mXml.addElement("coordinates")); mXml.popAddPoint(); // Point } mXml.popAddPoint(); break; } case LINE_OBJECT: case POLYLINE_OBJECT: case HLINE_OBJECT: case VLINE_OBJECT: case ROW_OBJECT: case COLUMN_OBJECT: { mXml.pushAddPoint(mXml.addElement("LineString")); mXml.addText(QString::number(order).toAscii().data(), mXml.addElement("drawOrder")); mXml.addText("1", mXml.addElement("tessellate")); QStringList coords; vector<LocationType> vertices; if (pObject->getGraphicObjectType() == POLYLINE_OBJECT) { vertices = static_cast<PolylineObject*>(pObject)->getVertices(); } else { LocationType ll = pObject->getLlCorner(); LocationType ur = pObject->getUrCorner(); vertices.push_back(ll); vertices.push_back(ur); } for (vector<LocationType>::const_iterator vertex = vertices.begin(); vertex != vertices.end(); ++vertex) { LocationType geo = pGeoElement->convertPixelToGeocoord(*vertex); coords << QString("%1,%2").arg(geo.mY, 0, 'f', 10).arg(geo.mX, 0, 'f', 10); } mXml.addText(coords.join(" ").toAscii().data(), mXml.addElement("coordinates")); mXml.popAddPoint(); // LineString break; } case RECTANGLE_OBJECT: case TRIANGLE_OBJECT: case POLYGON_OBJECT: { mXml.pushAddPoint(mXml.addElement("Polygon")); mXml.addText(QString::number(order).toAscii().data(), mXml.addElement("drawOrder")); mXml.addText("1", mXml.addElement("tessellate")); mXml.pushAddPoint(mXml.addElement("LinearRing", mXml.addElement("outerBoundaryIs"))); QStringList coords; vector<LocationType> vertices; LocationType ll = pObject->getLlCorner(); LocationType ur = pObject->getUrCorner(); LocationType center = (ll + ur); center.mX /= 2.0; center.mY /= 2.0; if (pObject->getGraphicObjectType() == RECTANGLE_OBJECT) { vertices.push_back(ll); vertices.push_back(LocationType(ll.mX, ur.mY)); vertices.push_back(ur); vertices.push_back(LocationType(ur.mX, ll.mY)); } else if (pObject->getGraphicObjectType() == TRIANGLE_OBJECT) { double apex = pObject->getApex(); vertices.push_back(ll); vertices.push_back(LocationType(ur.mX, ll.mY)); vertices.push_back(LocationType(ll.mX + apex * (ur.mX - ll.mX), ur.mY)); vertices.push_back(ll); } else { vertices = static_cast<PolygonObject*>(pObject)->getVertices(); } QPointF qcenter(center.mX, center.mY); QMatrix matrix; matrix.rotate(pObject->getRotation()); for (vector<LocationType>::const_iterator vertex = vertices.begin(); vertex != vertices.end(); ++vertex) { QPointF point(vertex->mX - center.mX, vertex->mY - center.mY); point = point * matrix; point += qcenter; LocationType geo = pGeoElement->convertPixelToGeocoord(LocationType(point.x(), point.y())); coords << QString("%1,%2").arg(geo.mY, 0, 'f', 10).arg(geo.mX, 0, 'f', 10); } mXml.addText(coords.join(" ").toAscii().data(), mXml.addElement("coordinates")); mXml.popAddPoint(); // LinearRing mXml.popAddPoint(); // Polygon break; } default: // not supported break; } mXml.popAddPoint(); // Placemark } mXml.popAddPoint(); // Folder }
vector<Feature*> ShapeFile::addFeatures(GraphicElement* pGraphicElement, GraphicObject* pObject, RasterElement* pGeoref, string& message) { vector<Feature*> features; message.clear(); if (pGraphicElement == NULL) { message = "Features cannot be added because the data element is invalid!"; return features; } if (pGeoref == NULL || !pGeoref->isGeoreferenced()) { message = "No georeferencing information can be found."; return features; } // Do not allow erase or toggle objects if (pObject != NULL) { if (pObject->getDrawMode() != DRAW) { message = "The " + pObject->getName() + " object is an erase or toggle object, so a feature " "will not be added."; return features; } } // Get the objects list<GraphicObject*> objects; if (pObject != NULL) { objects.push_back(pObject); } else { GraphicGroup* pGroup = pGraphicElement->getGroup(); if (pGroup != NULL) { // If the element is displayed in an annotation layer, use the selected objects AnnotationLayer* pAnnotationLayer = dynamic_cast<AnnotationLayer*>(pGroup->getLayer()); if (pAnnotationLayer != NULL) { pAnnotationLayer->getSelectedObjects(objects); } if (objects.empty()) { objects = pGroup->getObjects(); } } } // Create the features string elementName = pGraphicElement->getName(); const DynamicObject* pMetadata = getSourceMetadata(*pGraphicElement); switch (mShape) { case ShapefileTypes::POINT_SHAPE: { if (dynamic_cast<AnnotationElement*>(pGraphicElement) != NULL) { if (objects.empty()) { message = "Cannot create a shape file from an empty element."; return features; } // Get names of attributes which should be copied/exported. vector<string> attrNames; const DynamicObject* pAttributeMetadata = getSourceAttributeMetadata(*pGraphicElement); if (pAttributeMetadata != NULL) { pAttributeMetadata->getAttributeNames(attrNames); } for (list<GraphicObject*>::const_iterator it = objects.begin(); it != objects.end(); ++it) { GraphicObject* pCurrentObject = *it; if (pCurrentObject != NULL) { // Do not allow erase or toggle objects if (pCurrentObject->getDrawMode() != DRAW) { continue; } string objectName = pCurrentObject->getName(); vector<LocationType> vertices; pCurrentObject->getRotatedExtents(vertices); // Each point created from this object uses the same metadata. int idx = -1; if (pMetadata != NULL) { idx = getAttributeIndex(*pCurrentObject, *pMetadata); } LocationType pixel; for (vector<LocationType>::const_iterator verticesIter = vertices.begin(); verticesIter != vertices.end(); ++verticesIter) { // Add the feature SessionItem* pSessionItem = pGraphicElement; if (pObject != NULL) { pSessionItem = pObject; } Feature* pFeature = new Feature(pSessionItem); features.push_back(pFeature); mFeatures.push_back(pFeature); VERIFYNR(pFeature->attach(SIGNAL_NAME(Subject, Modified), Slot(this, &ShapeFile::shapeModified))); // Fields pFeature->addField("Name", string()); if (!elementName.empty()) { if (pObject != NULL) { pFeature->setFieldValue("Name", elementName + ": " + pObject->getName()); } else { pFeature->setFieldValue("Name", elementName + ": " + objectName); } } pixel.mX = verticesIter->mX + 0.5; pixel.mY = verticesIter->mY + 0.5; QString pixelName = "(" + QString::number(verticesIter->mX + 1) + ", " + QString::number(verticesIter->mY + 1) + ")"; pFeature->setFieldValue("Pixel", pixelName.toStdString()); if (idx > -1 && pAttributeMetadata != NULL) { copyMetadata(attrNames, idx, *pAttributeMetadata, *pFeature); } LocationType geo = pGeoref->convertPixelToGeocoord(*verticesIter); pFeature->addVertex(geo.mY, geo.mX); } } } } else { // The BitMaskIterator does not support negative extents and // the BitMask does not correctly handle the outside flag so // the BitMaskIterator is used for cases when the outside flag is true and // the BitMask is used for cases when the outside flag is false AoiElement* pAoiElement = dynamic_cast<AoiElement*>(pGraphicElement); VERIFYRV(pAoiElement != NULL, features); const BitMask* pMask = pAoiElement->getSelectedPoints(); if (pObject != NULL) { pMask = pObject->getPixels(); if (pMask == NULL) { message = "The " + pObject->getName() + " object cannot be represented by the " + StringUtilities::toDisplayString(mShape) + " shape type, so a feature will not be added."; return features; } } if (pMask != NULL) { BitMaskIterator maskIt(pMask, pGeoref); if ((maskIt.getCount() > 0 && pMask->isOutsideSelected() == true) || (pMask->getCount() > 0 && pMask->isOutsideSelected() == false)) { // Add features for each selected pixel int startColumn = 0; int endColumn = 0; int startRow = 0; int endRow = 0; if (pMask->isOutsideSelected() == true) { maskIt.getBoundingBox(startColumn, startRow, endColumn, endRow); } else { pMask->getBoundingBox(startColumn, startRow, endColumn, endRow); } LocationType pixel; for (int i = startColumn; i <= endColumn; i++) { for (int j = startRow; j <= endRow; j++) { if ((maskIt.getPixel(i, j) && pMask->isOutsideSelected() == true) || (pMask->getPixel(i, j) && pMask->isOutsideSelected() == false)) { // Add the feature SessionItem* pSessionItem = pGraphicElement; if (pObject != NULL) { pSessionItem = pObject; } Feature* pFeature = new Feature(pSessionItem); features.push_back(pFeature); mFeatures.push_back(pFeature); VERIFYNR(pFeature->attach(SIGNAL_NAME(Subject, Modified), Slot(this, &ShapeFile::shapeModified))); pixel.mX = i + 0.5; pixel.mY = j + 0.5; // Fields pFeature->addField("Name", string()); pFeature->addField("Pixel", string()); if (!elementName.empty()) { if (pObject != NULL) { pFeature->setFieldValue("Name", elementName + ": " + pObject->getName()); } else { pFeature->setFieldValue("Name", elementName); } } QString pixelName = "(" + QString::number(i + 1) + ", " + QString::number(j + 1) + ")"; pFeature->setFieldValue("Pixel", pixelName.toStdString()); // Vertex pixel = pGeoref->convertPixelToGeocoord(pixel); pFeature->addVertex(pixel.mY, pixel.mX); // Longitude as x-coord } } } } } } } break; case ShapefileTypes::POLYLINE_SHAPE: { if (objects.empty()) { message = "Cannot create a shape file from an empty element."; return features; } // Get names of attributes which should be copied/exported. vector<string> attrNames; const DynamicObject* pAttributeMetadata = getSourceAttributeMetadata(*pGraphicElement); if (pAttributeMetadata != NULL) { pAttributeMetadata->getAttributeNames(attrNames); } for (list<GraphicObject*>::const_iterator it = objects.begin(); it != objects.end(); ++it) { GraphicObject* pCurrentObject = *it; if (pCurrentObject != NULL) { GraphicObjectType objectType = pCurrentObject->getGraphicObjectType(); if ((objectType == LINE_OBJECT) || (objectType == POLYLINE_OBJECT) || (objectType == HLINE_OBJECT) || (objectType == VLINE_OBJECT)) { // Do not allow erase or toggle objects if (pCurrentObject->getDrawMode() != DRAW) { continue; } string objectName = pCurrentObject->getName(); vector<LocationType> vertices; pCurrentObject->getRotatedExtents(vertices); if (vertices.empty() == false) { Feature* pFeature = new Feature(pCurrentObject); features.push_back(pFeature); mFeatures.push_back(pFeature); VERIFYNR(pFeature->attach(SIGNAL_NAME(Subject, Modified), Slot(this, &ShapeFile::shapeModified))); pFeature->addField("Name", string()); if (!elementName.empty()) { pFeature->setFieldValue("Name", elementName + ": " + objectName); } // Copy attributes. if ((pMetadata != NULL) && (pAttributeMetadata != NULL)) { int idx = getAttributeIndex(*pCurrentObject, *pMetadata); if (idx > -1) { copyMetadata(attrNames, idx, *pAttributeMetadata, *pFeature); } } for (vector<LocationType>::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter) { LocationType geo = pGeoref->convertPixelToGeocoord(*iter); pFeature->addVertex(geo.mY, geo.mX); } } } } } } break; case ShapefileTypes::POLYGON_SHAPE: { if (objects.empty()) { message = "Cannot create a shape file from an empty element."; return features; } // Get names of attributes which should be copied/exported. vector<string> attrNames; const DynamicObject* pAttributeMetadata = getSourceAttributeMetadata(*pGraphicElement); if (pAttributeMetadata != NULL) { pAttributeMetadata->getAttributeNames(attrNames); } for (list<GraphicObject*>::const_iterator it = objects.begin(); it != objects.end(); ++it) { GraphicObject* pCurrentObject = *it; if (pCurrentObject != NULL) { GraphicObjectType objectType = pCurrentObject->getGraphicObjectType(); if ((objectType == RECTANGLE_OBJECT) || (objectType == ROUNDEDRECTANGLE_OBJECT) || (objectType == ELLIPSE_OBJECT) || (objectType == TRIANGLE_OBJECT) || (objectType == POLYGON_OBJECT) || (objectType == ARC_OBJECT)) { // Do not allow erase or toggle objects if (pCurrentObject->getDrawMode() != DRAW) { continue; } string objectName = pCurrentObject->getName(); vector<LocationType> vertices; pCurrentObject->getRotatedExtents(vertices); if (vertices.empty() == false) { // To represent non-polygon objects as polygons, add the first vertex as the last vertex if (objectType != POLYGON_OBJECT) { vertices.push_back(vertices.front()); } Feature* pFeature = new Feature(pCurrentObject); features.push_back(pFeature); mFeatures.push_back(pFeature); VERIFYNR(pFeature->attach(SIGNAL_NAME(Subject, Modified), Slot(this, &ShapeFile::shapeModified))); pFeature->addField("Name", string()); if (!elementName.empty()) { pFeature->setFieldValue("Name", elementName + ": " + objectName); } // Copy attributes. if ((pMetadata != NULL) && (pAttributeMetadata != NULL)) { int idx = getAttributeIndex(*pCurrentObject, *pMetadata); if (idx > -1) { copyMetadata(attrNames, idx, *pAttributeMetadata, *pFeature); } } for (vector<LocationType>::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter) { LocationType geo = pGeoref->convertPixelToGeocoord(*iter); pFeature->addVertex(geo.mY, geo.mX); } } } } } } break; case ShapefileTypes::MULTIPOINT_SHAPE: { if (dynamic_cast<AnnotationElement*>(pGraphicElement) != NULL) { if (objects.empty()) { message = "Cannot create a shape file from an empty element."; return features; } // Get names of attributes which should be copied/exported. vector<string> attrNames; const DynamicObject* pAttributeMetadata = getSourceAttributeMetadata(*pGraphicElement); if (pAttributeMetadata != NULL) { pAttributeMetadata->getAttributeNames(attrNames); } for (list<GraphicObject*>::const_iterator it = objects.begin(); it != objects.end(); ++it) { GraphicObject* pCurrentObject = *it; if (pCurrentObject != NULL) { // Do not allow erase or toggle objects if (pCurrentObject->getDrawMode() != DRAW) { continue; } Feature* pFeature = new Feature(pGraphicElement); features.push_back(pFeature); mFeatures.push_back(pFeature); VERIFYNR(pFeature->attach(SIGNAL_NAME(Subject, Modified), Slot(this, &ShapeFile::shapeModified))); // Fields pFeature->addField("Name", string()); if (!elementName.empty()) { if (pObject != NULL) { pFeature->setFieldValue("Name", elementName + ": " + pObject->getName()); } else { pFeature->setFieldValue("Name", elementName); } } // Copy attributes. if ((pMetadata != NULL) && (pAttributeMetadata != NULL)) { int idx = getAttributeIndex(*pCurrentObject, *pMetadata); if (idx > -1) { copyMetadata(attrNames, idx, *pAttributeMetadata, *pFeature); } } vector<LocationType> vertices; pCurrentObject->getRotatedExtents(vertices); for (vector<LocationType>::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter) { LocationType geo = pGeoref->convertPixelToGeocoord(*iter); pFeature->addVertex(geo.mY, geo.mX); } } } } else { // The BitMaskIterator does not support negative extents and // the BitMask does not correctly handle the outside flag so // the BitMaskIterator is used for cases when the outside flag is true and // the BitMask is used for cases when the outside flag is false AoiElement* pAoiElement = dynamic_cast<AoiElement*>(pGraphicElement); VERIFYRV(pAoiElement != NULL, features); const BitMask* pMask = pAoiElement->getSelectedPoints(); if (pObject != NULL) { pMask = pObject->getPixels(); if (pMask == NULL) { message = "The " + pObject->getName() + " object cannot be represented by the " + StringUtilities::toDisplayString(mShape) + " shape type, so a feature will not be added."; return features; } } if (pMask != NULL) { BitMaskIterator maskIt(pMask, pGeoref); if ((maskIt.getCount() > 0 && pMask->isOutsideSelected() == true) || (pMask->getCount() > 0 && pMask->isOutsideSelected() == false)) { // Add the feature SessionItem* pSessionItem = pGraphicElement; if (pObject != NULL) { pSessionItem = pObject; } Feature* pFeature = new Feature(pSessionItem); features.push_back(pFeature); mFeatures.push_back(pFeature); VERIFYNR(pFeature->attach(SIGNAL_NAME(Subject, Modified), Slot(this, &ShapeFile::shapeModified))); // Fields pFeature->addField("Name", string()); if (!elementName.empty()) { if (pObject != NULL) { pFeature->setFieldValue("Name", elementName + ": " + pObject->getName()); } else { pFeature->setFieldValue("Name", elementName); } } // Vertices int startColumn = 0; int endColumn = 0; int startRow = 0; int endRow = 0; if (pMask->isOutsideSelected() == true) { maskIt.getBoundingBox(startColumn, startRow, endColumn, endRow); } else { pMask->getBoundingBox(startColumn, startRow, endColumn, endRow); } LocationType pixel; for (int i = startColumn; i <= endColumn; i++) { for (int j = startRow; j <= endRow; j++) { if ((maskIt.getPixel(i, j) && pMask->isOutsideSelected() == true) || (pMask->getPixel(i, j) && pMask->isOutsideSelected() == false)) { pixel.mX = i + 0.5; pixel.mY = j + 0.5; pixel = pGeoref->convertPixelToGeocoord(pixel); pFeature->addVertex(pixel.mY, pixel.mX); // Longitude as x-coord } } } } } } } break; default: message = "Shape type not recognized."; return features; } if (features.empty()) { message = elementName + " has no objects that can be represented with the " + StringUtilities::toDisplayString(mShape) + " shape type, so no features can be added."; } return features; }