STRING MgResourceDefinitionManager::FormatMethodName(CREFSTRING methodName) { STRING errorText = methodName; errorText.append(L" ("); errorText.append(MgUtil::MultiByteToWideChar(m_container.getName())); errorText.append(L")"); return errorText; }
STRING DIR_LIB_SOURCE::makeFileName( const STRING& aPartName ) { // create a fileName for the sweet string, using a reversible // partname <-> fileName conversion protocol: STRING fileName = sourceURI + "/"; const char* rev = endsWithRev( aPartName ); if( rev ) { int basePartLen = rev - aPartName.c_str() - 1; // omit '/' separator fileName.append( aPartName, 0, basePartLen ); fileName += SWEET_EXT; fileName += '.'; fileName += rev; } else { fileName += aPartName; fileName += SWEET_EXT; } return fileName; }
// Returns the entire current element as a string STRING WfsGetFeatureParams::GetElementContents(MgXmlParser& parser) { STRING contents; if(parser.Current().Type() == keBeginElement) { MgXmlBeginElement& begin = (MgXmlBeginElement&)parser.Current(); STRING elementName = begin.Name().c_str(); do { contents.append(parser.Current().Contents()); if(parser.Current().Type() == keEndElement) { MgXmlEndElement& end = (MgXmlEndElement&)parser.Current(); if(_wcsicmp(end.Name().c_str(), elementName.c_str()) == 0) { // We've reached the end of the element break; } } } while(parser.Next()); } return contents; }
// Load level information int Level::LoadLevel(const STRING & path) { STRING file; file.assign(path.c_str()); STRING name = Port::FileName(file); file.append(Port::ReplacePath(STR("\\level.dat"))); NBT_Reader read = NBT_Reader(); read.Load(file); bool valid = false; NBTTag tag = read.ReadData(); // Read first compound while ((tag = read.ReadData()) != TAG_Unknown) { const NBTData * data = read.GetData(); if (!data) continue; if (!valid) { if (data->tag != TAG_Compound) continue; if (!data->name) continue; if (!StringCheck(data->name, "Data")) continue; valid = true; } switch (data->tag) { case TAG_Int: if (StringCheck(data->name, "version")) { info.version = data->i; } break; case TAG_Long: if (StringCheck(data->name, "RandomSeed")) { info.seed = data->l; } break; case TAG_String: if (StringCheck(data->name, "LevelName")) { info.name.assign((char *)data->bas, (char *)data->bas+data->size); } break; } } // Alpha if (info.name.empty()) info.name = name; return valid; }
MgSelection* TestProfilingService::CreateSelection(MgMap* map) { // make a selection in normal map STRING layerId; Ptr<MgLayerCollection> layers = map->GetLayers(); for (int i=0; i<layers->GetCount(); i++) { Ptr<MgLayerBase> layer = layers->GetItem(i); if(L"HydrographicPolygons" ==layer->GetName()) { layerId = layer->GetObjectId(); } } STRING selectionStr = L"<?xml version=\"1.0\" encoding=\"UTF-8\"?><FeatureSet><Layer id=\""; selectionStr.append(layerId); selectionStr.append(L"\"><Class id=\"SHP_Schema:HydrographicPolygons\"><ID>HQAAAA==</ID></Class></Layer></FeatureSet>"); MgSelection* selection = new MgSelection(map, selectionStr); return selection; }
void Initialize() { char* path = getenv(MapAgentStrings::PhysicalPath); if (NULL != path && strlen(path) > 0) { gConfigPath = MgUtil::MultiByteToWideChar(string(path)); } else { #if defined _WIN32 // IIS 6.0 does not honour APPL_PHYSICAL_PATH. Use exe path. wchar_t modPath[_MAX_PATH+1]; memset(modPath, 0, sizeof(wchar_t)*(_MAX_PATH+1)); if (GetModuleFileName(NULL, modPath, _MAX_PATH) > 4) { wchar_t* lastSlash = wcsrchr(modPath, L'\\'); if (NULL == lastSlash) { lastSlash = wcsrchr(modPath, L'/'); } if (NULL != lastSlash) { lastSlash++; *lastSlash = L'\0'; if (NULL != wcsstr(modPath, L"\\\\?\\")) { // skip past '\\?\' at front of string. gConfigPath = &(modPath[4]); } else { gConfigPath = modPath; } } } #endif } STRING configFile = gConfigPath; configFile.append(MapAgentStrings::WebConfig); string pathName = MgUtil::WideCharToMultiByte(configFile); DumpMessage("Loading configuration file: %s",pathName.c_str()); MG_TRY() MgInitializeWebTier(configFile); MG_CATCH_AND_THROW(L"FastCgiAgent.Initialize"); }
/*! * Add quotes around the string if it contains any whitespace. */ void AddQuotes(const T *whitespace) { if (_quoted.find_first_of(whitespace) != STRING::npos) { _quoted.insert(0, 1, '"'); _quoted.append(1, '"'); // If the last character (prior to adding the quotes) was a backslash, // it needs to be escaped now because it precedes a quote. // size_t quote = _quoted.size() - 1; if (_quoted[quote-1] == '\\') { size_t notSlash = _quoted.find_last_not_of('\\', quote-2); size_t numSlashes = quote - notSlash - 1; _quoted.insert(quote, numSlashes, '\\'); } } }
///////////////////////////////////////// // Write feature information as XML document. // MgByteReader* MgFeatureInformation::ToXml() { STRING xml; STRING xmlSelection = m_selection? m_selection->ToXml(false): L""; // TODO: define a schema for this XML xml.append(L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<FeatureInformation>\n"); size_t len = xmlSelection.length(); if(len > 0) { xml.reserve(len + 2048); xml.append(xmlSelection); } else { xml.reserve(2048); xml.append(L"<FeatureSet />\n"); } if(m_tooltip.length() > 0) { xml.append(L"<Tooltip>"); xml.append(MgUtil::ReplaceEscapeCharInXml(m_tooltip)); xml.append(L"</Tooltip>\n"); } else xml.append(L"<Tooltip />\n"); if(m_hyperlink.length() > 0) { xml.append(L"<Hyperlink>"); xml.append(MgUtil::ReplaceEscapeCharInXml(m_hyperlink)); xml.append(L"</Hyperlink>\n"); } else xml.append(L"<Hyperlink />\n"); if(m_properties != NULL) { for(int i = 0; i < m_properties->GetCount(); i++) { Ptr<MgStringProperty> prop = (MgStringProperty*)m_properties->GetItem(i); xml.append(L"<Property name=\""); xml.append(MgUtil::ReplaceEscapeCharInXml(prop->GetName())); xml.append(L"\" value=\""); xml.append(MgUtil::ReplaceEscapeCharInXml(prop->GetValue())); xml.append(L"\" />\n"); } } xml.append(L"</FeatureInformation>\n"); string xmlDoc = MgUtil::WideCharToMultiByte(xml); STRING mimeType = L"text/xml"; return MgUtil::GetByteReader(xmlDoc, &mimeType); }
void MgHtmlController::WriteSelectedFeatureAttributes(MgResourceService* resourceService, MgSelection* selectionSet, MgBatchPropertyCollection* attributes, REFSTRING xmlOut) { //Rather than doing a verbatim xml dump of MgBatchPropertyCollection, let's output something //that is more intuitive for client applications using this service operation to understand. //We could assume sorted layers in the MgBatchPropertyCollection, but play safe //and store our per-layer XML fragments in a bucket (keyed on layer name) and return //the merged bucket result at the end std::map<STRING, STRING> bucket; MgAgfReaderWriter agfRw; MgWktReaderWriter wktRw; Ptr<MgReadOnlyLayerCollection> selLayers = selectionSet->GetLayers(); if (NULL != selLayers.p) { // Our structure is as follows // // [0...n] <SelectedLayer> - A layer containing selected features // [1] <LayerMetadata> - Describing properties, its display name and its property type. Due to how QueryFeatureProperties works, display names // are used for property names for each feature. This element provides a reverse lookup table to ascertain the FDO system // property name for each attribute for client applications that require such information // [0...n] <Feature> - Each selected feature in the layer // [1] <Bounds> - The feature's bounding box [minx miny maxx maxy] // [0...n] <Property> - Property value for current feature for (INT32 i = 0; i < selLayers->GetCount(); i++) { Ptr<MgLayerBase> selLayer = selLayers->GetItem(i); STRING layerName = selLayer->GetName(); if (bucket.find(layerName) == bucket.end()) { STRING xml = L"<SelectedLayer id=\""; xml.append(selLayer->GetObjectId()); xml.append(L"\" name=\""); xml.append(selLayer->GetName()); xml.append(L"\">\n"); xml.append(L"<LayerMetadata>\n"); Ptr<MgClassDefinition> clsDef = selLayer->GetClassDefinition(); Ptr<MgPropertyDefinitionCollection> clsProps = clsDef->GetProperties(); Ptr<MgResourceIdentifier> layerId = selLayer->GetLayerDefinition(); //We need the property mappings of the source layer definition to compile our layer metadata std::auto_ptr<MdfModel::LayerDefinition> ldf(MgLayerBase::GetLayerDefinition(resourceService, layerId)); if (ldf.get() != NULL) { MdfModel::VectorLayerDefinition* vl = dynamic_cast<MdfModel::VectorLayerDefinition*>(ldf.get()); if(vl != NULL) { MdfModel::NameStringPairCollection* pmappings = vl->GetPropertyMappings(); for (int j=0; j<pmappings->GetCount(); j++) { STRING pTypeStr; MdfModel::NameStringPair* m = pmappings->GetAt(j); INT32 pidx = clsProps->IndexOf(m->GetName()); if (pidx >= 0) { Ptr<MgPropertyDefinition> propDef = clsProps->GetItem(pidx); INT32 pdType = propDef->GetPropertyType(); INT32 pType = MgPropertyType::Null; if (pdType == MgFeaturePropertyType::DataProperty) { pType = ((MgDataPropertyDefinition*)propDef.p)->GetDataType(); } else if (pdType == MgFeaturePropertyType::GeometricProperty) { pType = MgPropertyType::Geometry; } MgUtil::Int32ToString(pType, pTypeStr); xml.append(L"<Property>\n"); xml.append(L"<Name>"); xml.append(m->GetName()); xml.append(L"</Name>\n"); xml.append(L"<Type>"); xml.append(pTypeStr); xml.append(L"</Type>\n"); xml.append(L"<DisplayName>"); xml.append(m->GetValue()); xml.append(L"</DisplayName>\n"); xml.append(L"</Property>\n"); } } } } xml += L"</LayerMetadata>\n"; bucket[layerName] = xml; } } for (INT32 i = 0; i < attributes->GetCount(); i++) { Ptr<MgPropertyCollection> featProps = attributes->GetItem(i); INT32 lidx = featProps->IndexOf(L"_MgLayerName"); INT32 fidx = featProps->IndexOf(L"_MgFeatureBoundingBox"); //Must have both the _MgLayerName and _MgFeatureBoundingBox if (lidx < 0 || fidx < 0) continue; Ptr<MgStringProperty> layerNameProp = (MgStringProperty*)featProps->GetItem(lidx); Ptr<MgStringProperty> boundsProp = (MgStringProperty*)featProps->GetItem(fidx); //Locate the matching bucketed fragment to append to STRING layerName = layerNameProp->GetValue(); if (bucket.find(layerName) != bucket.end()) { //Good to go, write our feature to this bucketed fragment REFSTRING xml = bucket[layerName]; xml.append(L"<Feature>\n"); xml.append(L"<Bounds>"); xml.append(boundsProp->GetValue()); xml.append(L"</Bounds>\n"); for (INT32 p = 0; p < featProps->GetCount(); p++) { //Skip special properties if (p == lidx || p == fidx) continue; Ptr<MgNullableProperty> prop = dynamic_cast<MgNullableProperty*>(featProps->GetItem(p)); if (NULL != prop.p) { xml.append(L"<Property>\n"); xml.append(L"<Name>"); xml.append(prop->GetName()); xml.append(L"</Name>\n"); //We'll follow MgProperty spec. Null is represented by omission of <Value> if (!prop->IsNull()) { INT32 ptype = prop->GetPropertyType(); switch(ptype) { //case MgPropertyType::Blob: case MgPropertyType::Boolean: { xml.append(L"<Value>"); xml.append(((MgBooleanProperty*)prop.p)->GetValue() ? L"true" : L"false"); xml.append(L"</Value>\n"); } break; case MgPropertyType::Byte: { STRING sVal; MgUtil::Int32ToString((INT32)((MgByteProperty*)prop.p)->GetValue(), sVal); xml.append(L"<Value>"); xml.append(sVal); xml.append(L"</Value>\n"); } break; //case MgPropertyType::Clob: case MgPropertyType::DateTime: { Ptr<MgDateTime> dt = ((MgDateTimeProperty*)prop.p)->GetValue(); xml.append(L"<Value>"); xml.append(dt->ToXmlString()); xml.append(L"</Value>\n"); } break; case MgPropertyType::Decimal: case MgPropertyType::Double: { STRING sVal; MgUtil::DoubleToString(((MgDoubleProperty*)prop.p)->GetValue(), sVal); xml.append(L"<Value>"); xml.append(sVal); xml.append(L"</Value>\n"); } break; case MgPropertyType::Geometry: { try { Ptr<MgByteReader> agf = ((MgGeometryProperty*)prop.p)->GetValue(); Ptr<MgGeometry> geom = agfRw.Read(agf); STRING wkt = wktRw.Write(geom); xml.append(L"<Value>"); xml.append(wkt); xml.append(L"</Value>\n"); } catch (MgException* ex) //Bad geom maybe { SAFE_RELEASE(ex); } } break; case MgPropertyType::Int16: { STRING sVal; MgUtil::Int32ToString((INT32)((MgInt16Property*)prop.p)->GetValue(), sVal); xml.append(L"<Value>"); xml.append(sVal); xml.append(L"</Value>\n"); } break; case MgPropertyType::Int32: { STRING sVal; MgUtil::Int32ToString(((MgInt32Property*)prop.p)->GetValue(), sVal); xml.append(L"<Value>"); xml.append(sVal); xml.append(L"</Value>\n"); } break; case MgPropertyType::Int64: { STRING sVal; MgUtil::Int64ToString(((MgInt64Property*)prop.p)->GetValue(), sVal); xml.append(L"<Value>"); xml.append(sVal); xml.append(L"</Value>\n"); } break; case MgPropertyType::Single: { STRING sVal; MgUtil::SingleToString(((MgSingleProperty*)prop.p)->GetValue(), sVal); xml.append(L"<Value>"); xml.append(sVal); xml.append(L"</Value>\n"); } break; case MgPropertyType::String: { xml.append(L"<Value>"); xml.append(MgUtil::ReplaceEscapeCharInXml(((MgStringProperty*)prop.p)->GetValue())); xml.append(L"</Value>\n"); } break; } } xml.append(L"</Property>\n"); } } xml.append(L"</Feature>\n"); } } //Now merge the bucketed fragments for (std::map<STRING, STRING>::iterator it = bucket.begin(); it != bucket.end(); it++) { //Close off the <SelectedLayer> elements STRING xml = it->second; xml.append(L"</SelectedLayer>"); //Good to append to the final result xmlOut.append(xml); } } }
MgByteReader* MgHtmlController::CollectQueryMapFeaturesResult(MgResourceService* resourceService, INT32 requestData, MgFeatureInformation* featInfo, MgSelection* selectionSet, MgBatchPropertyCollection* attributes, MgByteReader* inlineSelection) { STRING xml; STRING tooltip; STRING hyperlink; STRING xmlSelection = selectionSet? selectionSet->ToXml(false): L""; if (NULL != featInfo) { tooltip = featInfo->GetTooltip(); hyperlink = featInfo->GetHyperlink(); } // TODO: Stil haven't defined a schema for v2.6. Should we? xml.append(L"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<FeatureInformation>\n"); size_t len = xmlSelection.length(); if(len > 0) { xml.reserve(len + 2048); xml.append(xmlSelection); } else { xml.reserve(2048); xml.append(L"<FeatureSet />\n"); } if (((requestData & REQUEST_TOOLTIP) == REQUEST_TOOLTIP) && !tooltip.empty()) { xml.append(L"<Tooltip>"); xml.append(MgUtil::ReplaceEscapeCharInXml(tooltip)); xml.append(L"</Tooltip>\n"); } else xml.append(L"<Tooltip />\n"); if (((requestData & REQUEST_HYPERLINK) == REQUEST_HYPERLINK) && !hyperlink.empty()) { xml.append(L"<Hyperlink>"); xml.append(MgUtil::ReplaceEscapeCharInXml(hyperlink)); xml.append(L"</Hyperlink>\n"); } else xml.append(L"<Hyperlink />\n"); if (((requestData & REQUEST_INLINE_SELECTION) == REQUEST_INLINE_SELECTION) && NULL != inlineSelection) { xml.append(L"<InlineSelectionImage>\n"); xml.append(L"<MimeType>"); xml.append(inlineSelection->GetMimeType()); xml.append(L"</MimeType>\n"); xml.append(L"<Content>"); MgByteSink sink(inlineSelection); Ptr<MgByte> bytes = sink.ToBuffer(); Ptr<MgMemoryStreamHelper> streamHelper = new MgMemoryStreamHelper((INT8*) bytes->Bytes(), bytes->GetLength(), false); std::string b64 = streamHelper->ToBase64(); STRING wb64 = MgUtil::MultiByteToWideChar(b64); xml.append(wb64); xml.append(L"</Content>\n"); xml.append(L"</InlineSelectionImage>\n"); } else xml.append(L"<InlineSelectionImage />\n"); if (((requestData & REQUEST_ATTRIBUTES) == REQUEST_ATTRIBUTES) && NULL != attributes) { xml.append(L"<SelectedFeatures>\n"); WriteSelectedFeatureAttributes(resourceService, selectionSet, attributes, xml); xml.append(L"</SelectedFeatures>\n"); } else xml.append(L"<SelectedFeatures />\n"); xml.append(L"</FeatureInformation>\n"); string xmlDoc = MgUtil::WideCharToMultiByte(xml); STRING mimeType = L"text/xml"; return MgUtil::GetByteReader(xmlDoc, &mimeType); }
// Create image saved in file int Level::CreateImage(const STRING & file) { if (cancel) return LVL_ERR_CANCEL; state = CREATEIMAGE; if (chunks.empty()) return LVL_ERR_NOCHUNKS; INT64 minX = MAPCOORD; INT64 minY = MAPCOORD; INT64 maxX = -MAPCOORD; INT64 maxY = -MAPCOORD; blocks = chunks.size() << 8; bool doRender = !(prefs.flags & CHUNKP_NORENDER); // Calculate size for (list<Chunk *>::iterator i = chunks.begin(); i != chunks.end(); ++i) { Chunk * chunk = (*i); if (!chunk->isValid()) continue; if (doRender) { COORDS x = chunk->GetX(); COORDS y = chunk->GetY(); if (x < minX) minX = x; if (y < minY) minY = y; if (x > maxX) maxX = x; if (y > maxY) maxY = y; } // And add to amount while we are processing amount += chunk->amount; } if (cancel) return LVL_ERR_CANCEL; if (doRender) { // No valid chunks? if (minX == MAPCOORD && minY == MAPCOORD && maxX == -MAPCOORD && maxY == -MAPCOORD) return LVL_ERR_INVALIDCHUNKS; prefs.rotation = abs((prefs.rotation / 90) * 90) % 360; float rad = (2 * 3.14159265f * prefs.rotation) / 360; UINT maxWidth = (UINT)(maxX - minX), maxHeight = (UINT)(maxY - minY); UINT width = (maxWidth + 1) * MAPX, height = (maxHeight + 1) * MAPY; // Foolproof if (width == 0 || height == 0) return LVL_ERR_INVALIDSIZE; // Rotate { float rCos = cos(rad); float rSin = sin(rad); rCos = (rCos < 0) ? -rCos : rCos; rSin = (rSin < 0) ? -rSin : rSin; UINT newWidth = UINT(width * rCos + height * rSin); UINT newHeight = UINT(height * rCos + width * rSin); width = newWidth; height = newHeight; } // Foolproof if (width == 0 || height == 0) return LVL_ERR_INVALIDSIZE; bool useCache = !prefs.cache.empty(); ImageCache cache(height, width); Image * image = 0; if (!useCache) { #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif // No more than 1 GiB if (width * height * sizeof(Color) > min(1073741824, Computer::GetAvailableMemory())) return LVL_ERR_TOOLARGE; try { image = new Image(height, width); if (image == 0) throw LVL_ERR_TOOLARGE; } catch (Level_Error error) { return error; } } else { STRING cacheFile = prefs.cache; cacheFile.append(STR("\\cache.bin")); cacheFile = Port::ReplacePath(cacheFile); if (!cache.Open(cacheFile)) return LVL_ERR_CACHE; } // Sort list //chunks.sort(compare_chunks); // Found duplicates //if (amountDuplicates > 0) // return LVL_ERR_DUPLICATES; // Create image int n = 0; for (list<Chunk *>::iterator i = chunks.begin(); i != chunks.end(); ++i, ++n) { Chunk * chunk = (*i); if (!chunk->isValid()) continue; Image * img = chunk->GetImage(); // One more try if (!img) { chunk->pref = prefs; chunk->CreateImage(); img = chunk->GetImage(); if (!img) continue; } UINT x = 0; UINT y = 0; switch (prefs.rotation) { case 90: x = (width - (UINT(chunk->GetY() - minY) * (MAPY))) - MAPY; y = UINT(chunk->GetX() - minX) * MAPX; break; case 180: x = (width - (UINT(chunk->GetX() - minX) * (MAPX))) - MAPX; y = (height - (UINT(chunk->GetY() - minY) * (MAPY))) - MAPY; break; case 270: x = UINT(chunk->GetY() - minY) * MAPY; y = (height - (UINT(chunk->GetX() - minX) * (MAPX))) - MAPX; break; case 0: default: x = UINT(chunk->GetX() - minX) * MAPX; y = UINT(chunk->GetY() - minY) * MAPY; } Color chnk[MAPX][MAPY] = {0}; // Write pixel for pixel for (UINT X = 0; X < MAPX; ++X) { for (UINT Y = 0; Y < MAPY; ++Y) { UINT XX = 0; UINT YY = 0; switch (prefs.rotation) { case 90: XX = Y; YY = (MAPX - 1) - X; break; case 180: XX = (MAPX - 1) - X; YY = (MAPY - 1) - Y; break; case 270: XX = (MAPY - 1) - Y; YY = X; break; case 0: default: XX = X; YY = Y; } if (!useCache) { image->SetPixel((height - (y + Y)) - 1, (x + X), img->GetPixel(YY, XX)); } else { Color * current = (*chnk) + ((MAPY - (Y+1)) + (MAPY * X)); Color c = img->GetPixel(YY, XX); memcpy(current, &c, sizeof(Color)); } } } if (useCache) { for (UINT X = 0; X < MAPX; ++X) { cache.Write(chnk[X], (height - y) - MAPY, (x + X), MAPY); } } done = ((float)n/(float)total); } done = 1; // No render mode if (prefs.flags & CHUNKP_NORENDER) { saved = true; if (!useCache) { delete image; } else { cache.Close(); } state = FINALIZING; return LVL_OK; } // Save image state = SAVING; // Normal save of image if (!useCache) { if (image->PrepareSave(file)) { for (UINT i = 0; i < width; ++i) { if (!image->SaveRow(i)) break; done = (float)i/(float)width; } saved = image->CloseSave(); } done = 1; delete image; } // Save from cache else { ImageSave sav; if (sav.Prepare(file, height, width)) { Color * line = new Color[height]; for (UINT i = 0; i < width; ++i) { cache.Read(&line, 0, i, height); if (!sav.Row(line)) break; done = (float)i/(float)width; } delete[] line; saved = sav.Close(); } cache.Close(); done = 1; } } else { saved = true; } state = FINALIZING; return saved ? LVL_OK : LVL_ERR_SAVE; }
// Build OGC filter XML stirngs based on the provided input filters. void WfsGetFeatureParams::BuildFilterStrings(CREFSTRING filters, CREFSTRING featureIds, CREFSTRING bbox) { // Create the required feature filters m_filterStrings = GetParenthesisedList(filters); if(m_filterStrings->GetCount() == 0) { // If no FILTER was specified, look for a BBOX if(bbox.length() > 0) { // Build a filter from the bounding box Ptr<MgStringCollection> bboxCoords = MgStringCollection::ParseCollection(bbox, L","); if(bboxCoords->GetCount() >= 4) { // TODO: Look into using StringStream and XmlElementEmitter for simplified generation // of these elements. STRING filterString = L"<ogc:Filter><ogc:BBOX><ogc:PropertyName>%MG_GEOM_PROP%</ogc:PropertyName><gml:Box><gml:coordinates>"; filterString.append(MgUtil::Trim(bboxCoords->GetItem(0))); filterString.append(L","); filterString.append(MgUtil::Trim(bboxCoords->GetItem(1))); filterString.append(L" "); filterString.append(MgUtil::Trim(bboxCoords->GetItem(2))); filterString.append(L","); filterString.append(MgUtil::Trim(bboxCoords->GetItem(3))); filterString.append(L"</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter>"); m_filterStrings->Add(filterString); } } // If no FILTER or BBOX, look for FEATUREID else if(featureIds.length() > 0) { // Build a filter from the list of feature Ids Ptr<MgStringCollection> featureIdList = MgStringCollection::ParseCollection(featureIds, L","); if(featureIdList->GetCount() > 0) { STRING filterString = L"<ogc:Filter>"; for(int i = 0; i < featureIdList->GetCount(); i++) { STRING thisFeatureId = MgUtil::Trim(featureIdList->GetItem(i)); if(thisFeatureId.length() > 0) { filterString.append(L"<ogc:GmlObjectId gml:id="); filterString.append(thisFeatureId); filterString.append(L"/>"); } } filterString.append(L"</ogc:Filter>"); m_filterStrings->Add(filterString); } } } }