[Cartoweb-users] calling id_recenter from search plugin

Oliver Christen oliver.christen at camptocamp.com
Thu May 10 02:52:07 EDT 2007


Ah right, mapserver, not postgres/postgis, I was confused.
Thanks Dirk

Regards
Oliver


  Hi,

  sounds like the same problem I had. If it is the same, it is a bug in 
  mapserver version 4.10 and possibly some 4.8. Have a look at the 
  attached ServerMapquery.php. I added some quotes in line 179 which 
  solved the problem. Try changing your 
  coreplugins\mapquery\server\ServerMapquery.php.


  Regards,
  Dirk



  WochteR wrote:
  > Hi,
  > I have troubles with recentering an object.
  > Plugin search works fine, but when I clicked on result I obtain this issue:
  >
  > Failure
  >
  > Class : SoapFaultWrapper
  > Message : MapServer error: Error in msDrawMap(): Failed to draw layer named 'zastavba'.
  >
  > Error in prepare_database(): Error executing POSTGIS DECLARE (the actual query) statement: 'DECLARE mycursor BINARY CURSOR FOR SELECT vyznamnost::text,gid::text,asbinary(force_collection(force_2d(the_geom)),'NDR'),gid::text from kzarovce_zastavba WHERE (gid = 'gid IN (620)') and (the_geom && setSRID( 'BOX3D(-469330.214285714 -1273120,-464958.785714286 -1270060)'::BOX3D,find_srid('','kzarovce_zastavba','the_geom') ))' 
  >
  > Postgresql reports the error as 'ERROR:  invalid input syntax for integer: "gid IN (620)"
  > '
  >
  > More Help:
  >
  > Error with POSTGIS data variable. You specified '<check your .map file>'.
  > Standard ways of specifiying are : 
  > (1) 'geometry_column from geometry_table' 
  > (2) 'geometry_column from (<sub query>) as foo using unique <column name> using SRID=<srid#>' 
  > Make sure you put in the 'using unique  <column name>' and 'using SRID=#' clauses in.
  > --------------------------
  >
  > It is very mysterious, because on my laptop it works good.
  > This issue is displayed from server where I moved working cartoweb project.
  > Need I change anything in php.ini or something else?
  > I don't know what to do...
  >
  > Thanx for advice
  >
  > wochter
  > _______________________________________________
  > Cartoweb-users mailing list
  > Cartoweb-users at lists.maptools.org
  > http://lists.maptools.org/mailman/listinfo/cartoweb-users
  >
  >   



------------------------------------------------------------------------------


  * @version $Id: ServerMapquery.php,v 1.33 2007-03-15 15:26:48 asaunier Exp $ */ /** * A service plugin to perform queries based on a set of selected id's * @package CorePlugins * @author Sylvain Pasche */ class ServerMapquery extends ServerPlugin { /** * @var Logger */ private $log; /** * Constructor */ public function __construct() { parent::__construct(); $this->log =& LoggerManager::getLogger(__CLASS__); } /** * Returns an array of query strings (for use in queryByAttributes), from * a set of id's and an attribute name. This query string can be used * in most case for layers. * @param string * @param string * @param array * @return array */ protected function genericQueryString($idAttribute, $idType, $selectedIds) { // FIXME: does queryByAttributes support multiple id's for dbf ? $queryString = array(); foreach($selectedIds as $id) { if ($idType == 'string') $queryString[] = "'[$idAttribute]' = '$id'"; else $queryString[] = "[$idAttribute] = $id"; } return array('(' . implode(' OR ', $queryString) . ')'); } /** * Returns an array of query strings (for use in queryByAttributes), from * a set of id's and an attribute name. This query string is to be used * on database kind of layers. * @param string * @param string * @param array * @return array */ protected function databaseQueryString($idAttribute, $idType, $selectedIds) { if (count($selectedIds) == 0) { return array('false'); } if ($idType == 'string') { $queryString = "'"; $queryString .= implode("', '", $selectedIds); $queryString .= "'"; } else { $queryString = implode(', ', $selectedIds); } return array("$idAttribute IN ($queryString)"); } /** * Returns true if layer is linked to a database * @param msLayer * @return boolean */ protected function isDatabaseLayer($msLayer) { switch ($msLayer->connectiontype) { case MS_POSTGIS: case MS_ORACLESPATIAL: return true; } return false; } /** * Extracts all shapes in the given msLayer, and returns them in an array * @param msLayer the layer from which to retrieve shapes * @return array the array of result shapes in the given layer */ protected function extractResults($layerId, $mayIgnore) { $msMapObj = $this->serverContext->getMapObj(); $layersInit = $this->serverContext->getMapInfo()->layersInit; $msLayer = $layersInit->getMsLayerById($msMapObj, $layerId); $msLayer->open(); $results = array(); $numResults = $msLayer->getNumResults(); $ignoreQueryThreshold = $this->getConfig()->ignoreQueryThreshold; if ($mayIgnore && is_numeric($ignoreQueryThreshold) && $numResults > $ignoreQueryThreshold) { $this->getServerContext()->addMessage($this, 'queryIgnored', sprintf(I18nNoop::gt( "Query spanned too many objects on layer '%s', it was ignored."), $layersInit->getLayerById($layerId)->label)); return array(); } $maxResults = $this->getConfig()->maxResults; if (is_numeric($maxResults) && $numResults > $maxResults) { $this->getServerContext()->addMessage($this, 'maxResultsHit', sprintf(I18nNoop::gt( "This query hit the maximum number of results on '%s', truncating results."), $layersInit->getLayerById($layerId)->label)); $numResults = $maxResults; } for ($i = 0; $i < $numResults; $i++) { $result = $msLayer->getResult($i); $shape = $msLayer->getShape($result->tileindex, $result->shapeindex); $results[] = $shape; } $msLayer->close(); return $results; } /** * Performs a query on a layer using attributes * @param ServerContext Server context * @param msLayer Layer to query * @param string The attribute name used by the query * @param string The query string to perform * @param boolean If true, a failure in the query is not fatal (empy array * returned) * @return array an array of shapes */ protected function queryLayerByAttributes(ServerContext $serverContext, $layerId, $idAttribute, $query, $mayFail = false) { $log =& LoggerManager::getLogger(__METHOD__); $msMapObj = $this->serverContext->getMapObj(); $layersInit = $this->serverContext->getMapInfo()->layersInit; $msLayer = $layersInit->getMsLayerById($msMapObj, $layerId); // Saves extent and sets it to max extent. $savedExtent = clone($msMapObj->extent); $maxExtent = $serverContext->getMaxExtent(); $msMapObj->setExtent($maxExtent->minx, $maxExtent->miny, $maxExtent->maxx, $maxExtent->maxy); $log->debug("queryLayerByAttributes layer: $msLayer->name " . "idAttribute: $idAttribute query: $query"); // Layer has to be activated for query. $msLayer->set('status', MS_ON); $ret = @$msLayer->queryByAttributes($idAttribute, '"'.$query.'"', MS_MULTIPLE); $this->log->debug('Query on layer ' . $msLayer->name . ": queryByAttributes($idAttribute, $query)"); if ($ret == MS_FAILURE) { if ($mayFail) { $serverContext->resetMsErrors(); return array(); } throw new CartoserverException('Attribute query returned no ' . "results. Layer: $msLayer->name, idAttribute: " . "$idAttribute, query: $query"); } $serverContext->checkMsErrors(); // restore extent $msMapObj->setExtent($savedExtent->minx, $savedExtent->miny, $savedExtent->maxx, $savedExtent->maxy); return $this->extractResults($layerId, false); } /** * Checks if layer's connection type is implemented * @param msLayer */ protected function checkImplementedConnectionTypes($msLayer) { $implementedConnectionTypes = array(MS_SHAPEFILE, MS_TILED_SHAPEFILE, MS_OGR, MS_POSTGIS, MS_ORACLESPATIAL); if (in_array($msLayer->connectiontype, $implementedConnectionTypes)) return; throw new CartoserverException('Layer to center on has an unsupported ' . "connection type: $msLayer->connectiontype"); } /** * Performs a query based on a set of selected id's on a given layer * @param IdSelection The selection to use for the query. It contains a * layer name and a set of id's * @param boolean If true, a failure in the query is not fatal (empy array * returned) * @return array an array of shapes */ public function queryByIdSelection(IdSelection $idSelection, $mayFail = false) { $serverContext = $this->getServerContext(); $layersInit = $serverContext->getMapInfo()->layersInit; $msLayer = $layersInit->getMsLayerById($serverContext->getMapObj(), $idSelection->layerId); $idAttribute = $idSelection->idAttribute; if (is_null($idAttribute)) { $idAttribute = $serverContext->getIdAttribute($idSelection->layerId); } if (is_null($idAttribute)) { throw new CartoserverException("can't find idAttribute for layer " . $idSelection->layerId); } $idType = $idSelection->idType; if (is_null($idType)) { $idType = $serverContext->getIdAttributeType($idSelection->layerId); } self::checkImplementedConnectionTypes($msLayer); $ids = Encoder::decode($idSelection->selectedIds, 'config'); // FIXME: can shapefiles support queryString for multiple id's ? // if yes, then improve this handling. if (self::isDatabaseLayer($msLayer)) $queryString = self::databaseQueryString($idAttribute, $idType, $ids); else $queryString = self::genericQueryString($idAttribute, $idType, $ids); $results = array(); foreach($queryString as $query) { $new_results = self::queryLayerByAttributes($serverContext, $idSelection->layerId, $idAttribute, $query, $mayFail); $results = array_merge($results, $new_results); } return $results; } /** * Performs a query based on a {@link Shape} object on a given layer. * @param string layerId * @param Shape geographic selection * @return array an array of shapes */ public function queryByShape($layerId, Shape $shape) { $msMapObj = $this->serverContext->getMapObj(); $layersInit = $this->serverContext->getMapInfo()->layersInit; $msLayer = $layersInit->getMsLayerById($msMapObj, $layerId); // layer has to be activated for query $msLayer->set('status', MS_ON); if ($shape instanceof Point) { $msPoint = ms_newPointObj(); $msPoint->setXY($shape->x, $shape->y); // no tolerance set by default, must be set in mapfile $ret = @$msLayer->queryByPoint($msPoint, MS_MULTIPLE, -1); $this->log->debug("Query on layer $layerId: " . "queryByPoint(msPoint, MS_MULTIPLE, -1)"); } elseif ($shape instanceof Bbox || $shape instanceOf Rectangle) { $msRect = ms_newRectObj(); $msRect->setextent($shape->minx, $shape->miny, $shape->maxx, $shape->maxy); $ret = @$msLayer->queryByRect($msRect); $this->log->debug("Query on layer $layerId: queryByRect(msRect)"); } elseif ($shape instanceof Polygon) { $msShape = ms_newShapeObj(MS_SHAPE_POLYGON); $msLine = ms_newLineObj(); foreach ($shape->points as $point) { $msLine->addXY($point->x, $point->y); } $msShape->add($msLine); $ret = @$msLayer->queryByShape($msShape); $this->log->debug("Query on layer $layerId: queryByShape(msShape)"); } elseif ($shape instanceof Circle) { //force mapscipt to consider radius units as geographic if ($msLayer->toleranceunits == MS_PIXELS) $msLayer->toleranceunits = $msMapObj->units; $msPoint = ms_newPointObj(); $msPoint->setXY($shape->x, $shape->y); $ret = @$msLayer->queryByPoint($msPoint, MS_MULTIPLE, $shape->radius); $this->log->debug("Query on layer $layerId: queryByPoint(" . "msPoint, MS_MULTIPLE, $shape->radius)"); } else { $this->CartoserverException(sprintf("Query can't be done on %s " . 'type selection', get_class($shape))); } $this->serverContext->resetMsErrors(); if ($ret != MS_SUCCESS || $msLayer->getNumResults() == 0) return array(); return $this->extractResults($layerId, true); } /** * Performs a query based on a bbox on a given layer * DEPRECATED: this method should no more be used. * Use {@link ServerMapquery::queryByShape()} instead * @param string layerId * @param Bbox * @return array an array of shapes */ public function queryByBbox($layerId, Bbox $bbox) { return $this->queryByShape($layerId, $bbox); } } ?> 


------------------------------------------------------------------------------


  _______________________________________________
  Cartoweb-users mailing list
  Cartoweb-users at lists.maptools.org
  http://lists.maptools.org/mailman/listinfo/cartoweb-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.maptools.org/pipermail/cartoweb-users/attachments/20070510/914ad60c/attachment.html


More information about the Cartoweb-users mailing list