bool ossimGmlSupportData::getImageGeometry( ossimKeywordlist& geomKwl ) const { bool success = true; if ( m_xmlDocument.valid() ) { vector< ossimRefPtr<ossimXmlNode> > xml_nodes; bool gotSensorImage = false; bool gotRectifiedImage = false; ossim_uint32 pcsCodeGrid = 32767; // only applies to rectified // Check the GMLJP2CoverageCollection attributes for the default namespace. ossimString defaultNamespaceStr( "" ); ossimString xpath_root = "/gmljp2:GMLJP2CoverageCollection"; xml_nodes.clear(); m_xmlDocument->findNodes( xpath_root, xml_nodes ); if ( xml_nodes.size() == 0 ) { // check if the default namespace is gmljp2 xpath_root = "/GMLJP2CoverageCollection"; m_xmlDocument->findNodes( xpath_root, xml_nodes ); } if ( xml_nodes.size() >= 1 ) { const ossimString defaultNamespaceIdentifierStr( "xmlns" ); ossimString defaultNamespacePrependStr = defaultNamespaceIdentifierStr + ":"; const ossimRefPtr<ossimXmlAttribute> defaultNamespaceAttribute = xml_nodes[0]->findAttribute( defaultNamespaceIdentifierStr ); ossimString defaultNamespaceSettingStr = defaultNamespaceAttribute->getValue(); // search for the attribute value in the other attributes const ossimXmlNode::AttributeListType& attributeList = xml_nodes[0]->getAttributes(); size_t nAttributes = attributeList.size(); for ( size_t i=0; i<nAttributes; ++i ) { const ossimRefPtr<ossimXmlAttribute> attribute = attributeList[i]; const ossimString& attribute_name = attribute->getName(); const ossimString& attribute_value = attribute->getValue(); if ( attribute_name != defaultNamespaceIdentifierStr && attribute_value == defaultNamespaceSettingStr ) { defaultNamespaceStr = attribute_name.after( defaultNamespacePrependStr ); defaultNamespaceStr += ":"; } } } // Check for a sensor image ossimString xpath0 = "/gmljp2:GMLJP2CoverageCollection/gmljp2:featureMember/gmljp2:GMLJP2ReferenceableGridCoverage/gml:domainSet/gmlcov:ReferenceableGridBySensorModel"; xpath0 = xpath0.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xml_nodes.clear(); m_xmlDocument->findNodes( xpath0, xml_nodes ); if ( xml_nodes.size() >= 1 ) { // we've got a sensor model image gotSensorImage = true; } else { const ossimString srsNameStr( "srsName" ); ossimString pcsCodeDefinitionStr( "http://www.opengis.net/def/crs/EPSG/0/" ); xpath0 = "/gmljp2:GMLJP2CoverageCollection/gmljp2:featureMember/gmljp2:GMLJP2RectifiedGridCoverage/gml:domainSet/gml:RectifiedGrid"; xpath0 = xpath0.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xml_nodes.clear(); m_xmlDocument->findNodes( xpath0, xml_nodes ); if ( xml_nodes.size() >= 1 ) { // we've got a rectified image gotRectifiedImage = true; const ossimRefPtr<ossimXmlAttribute> hrefAttribute = xml_nodes[0]->findAttribute( srsNameStr ); const ossimString& originSrsName = hrefAttribute->getValue(); ossimString pcsCodeGridStr = originSrsName.after( pcsCodeDefinitionStr.string() ); pcsCodeGrid = pcsCodeGridStr.toUInt32(); if ( pcsCodeGrid != 32767 ) { //--- // The ossimEpsgProjectionFactory will not pick up the origin latitude if code is // 4326 (geographic) so we use the projection name; else, the origin_latitude will // always be 0. This is so the gsd comes out correct for scale. //--- if ( pcsCodeGrid != 4326 ) // map projection { // Add the pcs code. geomKwl.add( ossimKeywordNames::PCS_CODE_KW, pcsCodeGridStr.c_str() ); } else // geographic { geomKwl.add( ossimKeywordNames::TYPE_KW, ossimString( "ossimEquDistCylProjection" ) ); } } } } /* Number of lines & samples, for either sensor or rectified imagery */ ossimString xpath_limits_low = "/gml:limits/gml:GridEnvelope/gml:low"; ossimString xpath_limits_high = "/gml:limits/gml:GridEnvelope/gml:high"; xpath_limits_low = xpath_limits_low.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath_limits_high = xpath_limits_high.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); bool gotLow = false; ossim_int32 lowX, lowY; ossimString xpath = xpath0 + xpath_limits_low; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); if ( xml_nodes.size() == 1 ) { const ossimString& lowerCorner = xml_nodes[0]->getText(); size_t spacePos = lowerCorner.find( ' ' ); ossimString lowerXString = lowerCorner.beforePos( spacePos ); ossimString lowerYString = lowerCorner.afterPos ( spacePos ); lowX = lowerXString.toInt32(); lowY = lowerYString.toInt32(); gotLow = true; } bool gotHigh = false; ossim_int32 highX = 0; ossim_int32 highY = 0; xpath = xpath0 + xpath_limits_high; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); if ( xml_nodes.size() == 1 ) { const ossimString& higherCorner = xml_nodes[0]->getText(); size_t spacePos = higherCorner.find( ' ' ); ossimString higherXString = higherCorner.beforePos( spacePos ); ossimString higherYString = higherCorner.afterPos ( spacePos ); highX = higherXString.toInt32(); highY = higherYString.toInt32(); gotHigh = true; } if ( gotHigh && gotLow ) { geomKwl.add( ossimKeywordNames::NUMBER_LINES_KW, highY - lowY + 1 ); geomKwl.add( ossimKeywordNames::NUMBER_SAMPLES_KW, highX - lowX + 1 ); } if ( gotSensorImage ) { const ossimString hrefStr( "xlink:href" ); const ossimString codeSpaceStr( "codeSpace" ); ossimString sensorModelHref( "" ); ossimString xpath_sensor_model = "/gmlcov:sensorModel"; xpath_sensor_model = xpath_sensor_model.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath = xpath0 + xpath_sensor_model; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); if ( xml_nodes.size() == 1 ) { const ossimRefPtr<ossimXmlAttribute> hrefAttribute = xml_nodes[0]->findAttribute( hrefStr ); sensorModelHref = hrefAttribute->getValue(); } ossimString sensorInstanceHref( "" ); ossimString xpath_sensor_typeOf = "/gmlcov:sensorInstance/sml:SimpleProcess/sml:typeOf"; xpath_sensor_typeOf = xpath_sensor_typeOf.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath = xpath0 + xpath_sensor_typeOf; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); if ( xml_nodes.size() == 1 ) { const ossimRefPtr<ossimXmlAttribute> hrefAttribute = xml_nodes[0]->findAttribute( hrefStr ); sensorInstanceHref = hrefAttribute->getValue(); } ossimSensorModel* sensor_model = 0; ossimString xpath_sensor_name = "/gmlcov:sensorInstance/sml:SimpleProcess/gml:name"; xpath_sensor_name = xpath_sensor_name.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath = xpath0 + xpath_sensor_name; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); int nSensorNames = (int)xml_nodes.size(); for ( int i=0; i<nSensorNames; ++i ) { const ossimString& sensorName = xml_nodes[i]->getText(); ossimProjectionFactoryRegistry* registry = ossimProjectionFactoryRegistry::instance(); ossimProjection* proj = registry->createProjection( sensorName ); // Is it a sensor model ? sensor_model = dynamic_cast<ossimSensorModel*>( proj ); if ( sensor_model != 0 ) { geomKwl.add( ossimKeywordNames::TYPE_KW, sensorName.c_str() ); break; } } if ( sensor_model == 0 ) { // Add debug message return false; } // Check if the sensor instance is typeOf the sensor model if ( sensorModelHref == sensorInstanceHref ) { const ossimString refStr( "ref" ); /* sml:setValue */ ossimString xpath_setValue = "/gmlcov:sensorInstance/sml:SimpleProcess/sml:configuration/sml:Settings/sml:setValue"; xpath_setValue = xpath_setValue.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath = xpath0 + xpath_setValue; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); size_t nXmlNodes = xml_nodes.size(); for( size_t i=0; i<nXmlNodes; ++i ) { const ossimString& elementValue = xml_nodes[i]->getText(); const ossimRefPtr<ossimXmlAttribute> refAttribute = xml_nodes[i]->findAttribute( refStr ); const ossimString& settingsRef = refAttribute->getValue(); bool successSetValue = sensor_model->getImageGeometry( settingsRef, elementValue, geomKwl ); success &= successSetValue; if ( !successSetValue ) { // Add debug message } } /* sml:setArrayValues */ ossimString xpath_setArrayValues = "/gmlcov:sensorInstance/sml:SimpleProcess/sml:configuration/sml:Settings/sml:setArrayValues"; xpath_setArrayValues = xpath_setArrayValues.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath = xpath0 + xpath_setArrayValues; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); nXmlNodes = xml_nodes.size(); for( size_t i=0; i<nXmlNodes; ++i ) { ossimString elementValue( "" ); const ossimRefPtr<ossimXmlAttribute> refAttribute = xml_nodes[i]->findAttribute( refStr ); const ossimString& settingsRef = refAttribute->getValue(); const ossimXmlNode::ChildListType& children = xml_nodes[i]->getChildNodes(); if ( children.size() > 0 ) { const ossimXmlNode::ChildListType& grandchildren = children[0]->getChildNodes(); if ( (grandchildren.size() > 1) && (grandchildren[1]->getTag() == ossimString( "sml:value")) ) { elementValue = grandchildren[1]->getText(); } } bool successSetArrayValues = sensor_model->getImageGeometry( settingsRef, elementValue, geomKwl ); success &= successSetArrayValues; if ( !successSetArrayValues ) { // Add debug message } } } } else if ( gotRectifiedImage ) { const ossimString srsNameStr( "srsName" ); ossimString pcsCodeDefinitionStr( "http://www.opengis.net/def/crs/EPSG/0/" ); /* axis labels for rectified imagery */ ossimString xpath_axisLabels = "/gml:axisLabels"; xpath_axisLabels = xpath_axisLabels.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); ossimString firstAxisLabelString( "" ); ossimString secondAxisLabelString( "" ); ossimString xpath = xpath0 + xpath_axisLabels; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); if ( xml_nodes.size() == 1 ) { const ossimString& axisLabelsString = xml_nodes[0]->getText(); size_t spacePos = axisLabelsString.find( ' ' ); firstAxisLabelString = axisLabelsString.beforePos( spacePos ); secondAxisLabelString = axisLabelsString.afterPos ( spacePos ); } /* origin */ ossim_uint32 pcsCodeOrigin = 32767; ossimString xpath_originPoint = "/gml:origin/gml:Point"; xpath_originPoint = xpath_originPoint.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath = xpath0 + xpath_originPoint; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); if ( xml_nodes.size() == 1 ) { const ossimString& originString = xml_nodes[0]->getChildTextValue( ossimString( "pos" ) ); size_t spacePos = originString.find( ' ' ); ossimString firstOriginString = originString.beforePos( spacePos ); ossimString secondOriginString = originString.afterPos ( spacePos ); const ossimRefPtr<ossimXmlAttribute> hrefAttribute = xml_nodes[0]->findAttribute( srsNameStr ); const ossimString& originSrsName = hrefAttribute->getValue(); ossimString pcsCodeOriginStr = originSrsName.after( pcsCodeDefinitionStr.string() ); pcsCodeOrigin = pcsCodeOriginStr.toUInt32(); if ( pcsCodeOrigin != 32767 ) { if ( pcsCodeOrigin != 4326 ) // map projection { /* Convert to geographic */ } if ( firstAxisLabelString == ossimString( "Lat" ) ) { geomKwl.add( ossimKeywordNames::ORIGIN_LATITUDE_KW, firstOriginString.c_str() ); geomKwl.add( ossimKeywordNames::CENTRAL_MERIDIAN_KW, secondOriginString.c_str() ); } else { geomKwl.add( ossimKeywordNames::ORIGIN_LATITUDE_KW, secondOriginString.c_str() ); geomKwl.add( ossimKeywordNames::CENTRAL_MERIDIAN_KW, firstOriginString.c_str() ); } } } /* offset vector */ ossimString xpath_offsetVector = "/gml:offsetVector"; xpath_offsetVector = xpath_offsetVector.replaceAllThatMatch( defaultNamespaceStr.c_str(), "" ); xpath = xpath0 + xpath_offsetVector; xml_nodes.clear(); m_xmlDocument->findNodes( xpath, xml_nodes ); size_t nNodes = xml_nodes.size(); for ( size_t i=0; i<nNodes; ++i ) { const ossimString& offsetVectorString = xml_nodes[i]->getText(); size_t spacePos = offsetVectorString.find( ' ' ); ossimString firstOffsetVectorString = offsetVectorString.beforePos( spacePos ); ossimString secondOffsetVectorString = offsetVectorString.afterPos ( spacePos ); const ossimRefPtr<ossimXmlAttribute> hrefAttribute = xml_nodes[i]->findAttribute( srsNameStr ); const ossimString& offsetVectorSrsName = hrefAttribute->getValue(); ossimString pcsCodeOffsetVectorStr = offsetVectorSrsName.after( pcsCodeDefinitionStr.string() ); ossim_uint32 pcsCodeOffsetVector = pcsCodeOffsetVectorStr.toUInt32(); if ( pcsCodeOffsetVector == 4326 ) { if ( firstAxisLabelString == ossimString( "Lat" ) ) { if ( firstOffsetVectorString.toDouble() != 0.0 ) { geomKwl.add( ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT, firstOffsetVectorString.c_str() ); } else { geomKwl.add( ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON, secondOffsetVectorString.c_str() ); } } else { if ( firstOffsetVectorString.toDouble() != 0.0 ) { geomKwl.add( ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LON, firstOffsetVectorString.c_str() ); } else { geomKwl.add( ossimKeywordNames::DECIMAL_DEGREES_PER_PIXEL_LAT, secondOffsetVectorString.c_str() ); } } } else // map projection if ( pcsCodeOffsetVector == pcsCodeGrid ) { if ( firstAxisLabelString == ossimString( "X" ) ) { if ( firstOffsetVectorString.toDouble() != 0.0 ) { geomKwl.add( ossimKeywordNames::METERS_PER_PIXEL_X_KW, firstOffsetVectorString.c_str() ); } else { geomKwl.add( ossimKeywordNames::METERS_PER_PIXEL_Y_KW, secondOffsetVectorString.c_str() ); } } else { if ( firstOffsetVectorString.toDouble() != 0.0 ) { geomKwl.add( ossimKeywordNames::METERS_PER_PIXEL_Y_KW, firstOffsetVectorString.c_str() ); } else { geomKwl.add( ossimKeywordNames::METERS_PER_PIXEL_X_KW, secondOffsetVectorString.c_str() ); } } } else { /* Need to perform a coordinate conversion on the offset vector to the pcs code of the grid */ } } } } return success; } // End: ossimGmlSupportData::getImageGeometry( geoKwl )
void Configuration::readApplicationSettings(xml_node<> *app) { xml_node<> *sess = singleChildElement(app, "session-management"); if (sess) { xml_node<> *dedicated = singleChildElement(sess, "dedicated-process"); xml_node<> *shared = singleChildElement(sess, "shared-process"); std::string tracking = singleChildElementValue(sess, "tracking", ""); if (dedicated && shared) throw WServer::Exception("<application-settings> requires either " "<dedicated-process> or <shared-process>, " "not both"); if (dedicated) { sessionPolicy_ = DedicatedProcess; setInt(dedicated, "max-num-sessions", maxNumSessions_); } if (shared) { sessionPolicy_ = SharedProcess; setInt(shared, "num-processes", numProcesses_); } if (!tracking.empty()) { if (tracking == "Auto") sessionTracking_ = CookiesURL; else if (tracking == "URL") sessionTracking_ = URL; else throw WServer::Exception("<session-tracking>: expecting 'Auto' " "or 'URL'"); } setInt(sess, "timeout", sessionTimeout_); setInt(sess, "bootstrap-timeout", bootstrapTimeout_); setInt(sess, "server-push-timeout", serverPushTimeout_); setBoolean(sess, "reload-is-new-session", reloadIsNewSession_); } std::string maxRequestStr = singleChildElementValue(app, "max-request-size", ""); if (!maxRequestStr.empty()) maxRequestSize_ = boost::lexical_cast< ::int64_t >(maxRequestStr) * 1024; std::string debugStr = singleChildElementValue(app, "debug", ""); if (!debugStr.empty()) { if (debugStr == "stack") errorReporting_ = ErrorMessageWithStack; else if (debugStr == "true") errorReporting_ = NoErrors; else if (debugStr == "false") errorReporting_ = ErrorMessage; else throw WServer::Exception("<debug>: expecting 'true', 'false'," "or 'stack'"); } setInt(app, "num-threads", numThreads_); xml_node<> *fcgi = singleChildElement(app, "connector-fcgi"); if (!fcgi) fcgi = app; // backward compatibility valgrindPath_ = singleChildElementValue(fcgi, "valgrind-path", valgrindPath_); runDirectory_ = singleChildElementValue(fcgi, "run-directory", runDirectory_); setInt(fcgi, "num-threads", numThreads_); // backward compatibility < 3.2.0 xml_node<> *isapi = singleChildElement(app, "connector-isapi"); if (!isapi) isapi = app; // backward compatibility setInt(isapi, "num-threads", numThreads_); // backward compatibility < 3.2.0 std::string maxMemoryRequestSizeStr = singleChildElementValue(isapi, "max-memory-request-size", ""); if (!maxMemoryRequestSizeStr.empty()) { isapiMaxMemoryRequestSize_ = boost::lexical_cast< ::int64_t > (maxMemoryRequestSizeStr) * 1024; } setInt(app, "session-id-length", sessionIdLength_); /* * If a session-id-prefix is defined in the configuration file, then * we loose the prefix defined by the connector (e.g. wthttpd), but who * would do such a thing ? */ connectorSessionIdPrefix_ = singleChildElementValue(app,"session-id-prefix", connectorSessionIdPrefix_); setBoolean(app, "send-xhtml-mime-type", xhtmlMimeType_); if (xhtmlMimeType_) LOG_WARN("ignoring send-xhtml-mime-type setting: HTML5 is now always used"); redirectMsg_ = singleChildElementValue(app, "redirect-message", redirectMsg_); setBoolean(app, "behind-reverse-proxy", behindReverseProxy_); setBoolean(app, "strict-event-serialization", serializedEvents_); setBoolean(app, "web-sockets", webSockets_); setBoolean(app, "inline-css", inlineCss_); setBoolean(app, "persistent-sessions", persistentSessions_); uaCompatible_ = singleChildElementValue(app, "UA-Compatible", ""); setBoolean(app, "progressive-bootstrap", progressiveBoot_); if (progressiveBoot_) setBoolean(app, "split-script", splitScript_); setBoolean(app, "session-id-cookie", sessionIdCookie_); setBoolean(app, "cookie-checks", cookieChecks_); std::string plainAjaxSessionsRatioLimit = singleChildElementValue(app, "plain-ajax-sessions-ratio-limit", ""); if (!plainAjaxSessionsRatioLimit.empty()) maxPlainSessionsRatio_ = boost::lexical_cast<float>(plainAjaxSessionsRatioLimit); setBoolean(app, "ajax-puzzle", ajaxPuzzle_); setInt(app, "indicator-timeout", indicatorTimeout_); setInt(app, "double-click-timeout", doubleClickTimeout_); std::vector<xml_node<> *> userAgents = childElements(app, "user-agents"); for (unsigned i = 0; i < userAgents.size(); ++i) { xml_node<> *userAgentsList = userAgents[i]; std::string type; if (!attributeValue(userAgentsList, "type", type)) throw WServer::Exception("<user-agents> requires attribute 'type'"); std::string mode; attributeValue(userAgentsList, "mode", mode); AgentList *list; if (type == "ajax") { list = &ajaxAgentList_; if (mode == "black-list") ajaxAgentWhiteList_ = false; else if (mode == "white-list") ajaxAgentWhiteList_ = true; else throw WServer::Exception ("<user-agents type=\"ajax\" requires attribute 'mode' with value " "\"white-list\" or \"black-list\""); } else if (type == "bot") list = &botList_; else throw WServer::Exception ("<user-agents> requires attribute 'type' with value " "\"ajax\" or \"bot\""); std::vector<xml_node<> *> agents = childElements(userAgentsList, "user-agent"); for (unsigned j = 0; j < agents.size(); ++j) list->push_back(elementValue(agents[j], "user-agent")); } xml_node<> *properties = singleChildElement(app, "properties"); if (properties) { std::vector<xml_node<> *> nodes = childElements(properties, "property"); for (unsigned i = 0; i < nodes.size(); ++i) { xml_node<> *property = nodes[i]; std::string name; if (!attributeValue(property, "name", name)) throw WServer::Exception("<property> requires attribute 'name'"); std::string value = elementValue(property, "property"); if (name == "approot") name = "appRoot"; if (name == "appRoot" && !appRoot_.empty()) LOG_WARN("ignoring configuration property 'appRoot' (" << value << ") because was already set to " << appRoot_); else properties_[name] = value; } } }