map = $map; if (isset($_GET["mode"])) { $this->mode = $_GET["mode"]; } else { $this->mode= "search"; } if (isset($_GET["imgxy"])) { $imgxy_str = $_GET["imgxy"]; $this->imgxy_arr = explode(" ", $imgxy_str); } // Take groups for query from URL or SESSION-ID if (isset($_GET["groups"])) { $this->querygroups[] = $_GET["groups"]; } else { $this->querygroups = $_SESSION["groups"]; } $this->highlightSelected = $_SESSION["highlightSelected"]; //$this->limitResult = $_SESSION["limitResult"]; $this->scale = $_SESSION["geo_scale"]; $this->infoWin = $_SESSION["infoWin"]; $this->mapwidth = $_SESSION["mapwidth"]; $this->mapheight = $_SESSION["mapheight"]; $this->GEOEXT = $_SESSION["GEOEXT"]; $this->autoZoom = $_SESSION["autoZoom"]; $this->zoomAll = $_SESSION["zoomAll"]; $this->grouplist = $_SESSION["grouplist"]; $_SESSION["mode"] = $this->mode; // RESTRICT QUERY TO VISIBLE LAYERS IN THE SCOPE OF CURRENT SCALE if ($this->mode != search) { setGroups($this->map, $this->querygroups, $this->scale, 0, 1); } } function q_processQuery() { if ($this->mode != "search") { $this->q_checkZoomSettings(); $this->q_setExtents(); $this->q_execMapQuery(); $this->q_printGroups(); } else { $this->q_checkZoomSettings(); $this->q_execAttributeQuery(); $this->q_printAttributeQuery(); } // Write result to session if ($this->mode != "iquery") { $_SESSION['JSON_Results'] = $this->allResStr; } } function q_returnQueryResult() { if ($this->numResultsTotal > 0) { return $this->allResStr; } else { return 0; } } function q_returnNumResultsTotal() { return $this->numResultsTotal; } // ======================== PRIVATE FUNCTIONS =====================// /* * CHECK SETTINGS FOR ZOOM/AUTOZOOM **/ function q_checkZoomSettings() { // SELECTION (nquery) and SEARCH: check for zoom settings if ($this->mode != "query") { // Check for autozoom if (preg_match("/$this->mode/i", $this->autoZoom)) { $this->doAutoZoom = 1; $this->zoomFull = 1; } // Check for adding 'Zoom2All' button if (preg_match("/$this->mode/i", $this->zoomAll)) { $this->doZoomAll = 1; $this->zoomFull = 1; } $_SESSION["activegroup"] = $this->querygroups[0]; } } /* * SET MAP EXTENTS **/ function q_setExtents() { $this->minx_geo = $this->GEOEXT["minx"]; $this->maxx_geo = $this->GEOEXT["maxx"]; $this->miny_geo = $this->GEOEXT["miny"]; $this->maxy_geo = $this->GEOEXT["maxy"]; $this->xdelta_geo = $this->maxx_geo - $this->minx_geo; $this->ydelta_geo = $this->maxy_geo - $this->miny_geo; } /* * EXECUTE QUERY **/ function q_execMapQuery() { // query by point if (count($this->imgxy_arr) == 2) { $this->pointQuery = 1; $this->x_pix = $this->imgxy_arr[0]; $this->y_pix = $this->imgxy_arr[1]; $x_geo = $this->minx_geo + (($this->x_pix/$this->mapwidth) * $this->xdelta_geo); $y_geo = $this->maxy_geo - (($this->y_pix/$this->mapheight) * $this->ydelta_geo); $XY_geo = ms_newPointObj(); $XY_geo->setXY($x_geo, $y_geo); $searchArea = -1; // ===> USE TOLERANCE IN MAP FILE FOR EACH LAYER <=== // Set $this->map->extent to values of current map extent // otherwise values of TOLERANCE in map file are not interpreted correctly $this->map->setExtent($this->GEOEXT['minx'], $this->GEOEXT['miny'], $this->GEOEXT['maxx'], $this->GEOEXT['maxy']); // Use '@' to avoid warning if query found nothing @$this->map->queryByPoint($XY_geo, MS_MULTIPLE, $searchArea); $XY_geo->free(); // query by Rectangle } else { $this->pointQuery = 0; $minx_pix = $this->imgxy_arr[0]; $miny_pix = $this->imgxy_arr[1]; $maxx_pix = $this->imgxy_arr[2]; $maxy_pix = $this->imgxy_arr[3]; if ($minx_pix == $maxx_pix) $maxx_pix = $maxx_pix + 2; // increase max extent if min==max if ($miny_pix == $maxy_pix) $maxy_pix = $maxy_pix - 2; // -- " -- $this->minx_sel_geo = $this->minx_geo + (($minx_pix/$this->mapwidth) * $this->xdelta_geo); $this->miny_sel_geo = $this->maxy_geo - (($maxy_pix/$this->mapheight) * $this->ydelta_geo); $this->maxx_sel_geo = $this->minx_geo + (($maxx_pix/$this->mapwidth) * $this->xdelta_geo); $this->maxy_sel_geo = $this->maxy_geo - (($miny_pix/$this->mapheight) * $this->ydelta_geo); $selrect = ms_newrectObj(); $selrect->setextent($this->minx_sel_geo, $this->miny_sel_geo, $this->maxx_sel_geo, $this->maxy_sel_geo); @$this->map->queryByRect($selrect); $selrect->free(); //$queryFile = "d:/webdoc/tmp/qresults.txt"; //$savedq = $this->map->savequery($queryFile); //printDebug($this->map->loadquery($queryFile)); //error_log( } } /* * PRINT RESULTS FOR GROUP **/ function q_printGroups() { $this->numResultsTotal = 0; $this->allResStr = "[ ["; // Write results for all query groups $c = 0; foreach ($this->grouplist as $grp){ if (in_array($grp->groupName, $this->querygroups, TRUE)) { $this->selHeaders = $grp->getResHeaders(); $glayerList = $grp->getLayers(); $this->grpNumResults = 0; $lp = 1; // Process all layers for group $this->layersResStr = ""; $glayerListCount = count($glayerList); $this->lc = 0; foreach ($glayerList as $l) { $this->glayer = $l; $layType = $this->q_printLayer(); //@@@@@@// // Add comma separator if more than one layer per group adds result row if ($this->query && $layType != 4) { if ($this->query->getLayNumResults() > 0 ) { $this->lc++; } } // Unset query variable (otherwise duplicated values in some cases) unset($this->query); } if ($this->grpNumResults > 0) { //error_log($this->grpNumResults); if ($c > 0) $this->allResStr .= ", "; $this->numResultsTotal += $this->grpNumResults; $this->printGrpResString($grp); //unset($this->query); $c++; } } } $zp = $this->q_printZoomParameters(); $this->allResStr .= "], $zp ]"; } function printGrpResString($grp) { $grpName = $grp->getGroupName(); $grpDesc = $grp->getDescription(); $grpResStr .= "{\"name\": \"$grpName\", \"description\": \"$grpDesc\", "; $grpResStr .= $this->fieldHeaderStr; $grpResStr .= $this->layersResStr; $grpResStr .= "]} "; $this->allResStr .= $grpResStr; } /* * PRINT RESULTS GROUP LAYER **/ function q_printLayer() { $this->qLayer = $this->map->getLayer($this->glayer->getLayerIdx()); $resFldList = $this->glayer->getResFields(); $qLayerType = $this->qLayer->type; $qLayerConnType = $this->qLayer->connectiontype; $this->qLayerName = $this->qLayer->name; // Exclude WMS and annotation layers and layers with no result fields defined if ($qLayerConnType != 7 && $qLayerType != 4 && $resFldList[0] != '0') { $XYLayerProperties = $this->glayer->getXYLayerProperties(); // Normal Layer if (!$XYLayerProperties) { $this->q_printStandardLayer(); //@@@@@@// // XY Layer } else { $this->q_printXYLayer(); //@@@@@@// } if ($this->query) { $this->fieldHeaderStr = $this->query->getFieldHeaderStr($this->selHeaders); $this->colspan = count($this->selHeaders) + 1; } // WMS layer } elseif ($qLayerType == 3 && $qLayerConnType == 7 ) { $this->fieldHeaderStr = ""; $this->q_printWMSLayer(); //@@@@@@// } if ($this->query && $qLayerType != 4) { //if ($this->qLayer->getNumResults() > 0) { if ($this->query->getLayNumResults() > 0) { $sep = $this->lc > 0 ? ", " : ""; $this->layersResStr .= $sep . $this->query->getResultString(); $this->grpNumResults += $this->query->getLayNumResults(); } } return $qLayerType; } /* * PRINT RESULTS FOR STANDARD LAYER **/ function q_printStandardLayer() { if ($this->qLayer->getNumResults() > 0) { $this->query = &new DQuery($this->map, $this->qLayer, $this->glayer, $this->zoomFull); // For Select function (nquery): get indexes of result shapes and max extent of all shapes if ($this->mode == "nquery") { $this->resultlayers[$this->qLayerName] = $this->query->returnResultindexes(); $resulttilelayers[$this->qLayerName] = $this->query->returnResultTileindexes(); $_SESSION['resulttilelayers'] = $resulttilelayers; $this->Extents[] = $this->query->returnMaxExtent(); } } } /* * PRINT RESULTS FOR XY LAYER **/ function q_printXYLayer() { $x_geo = $this->minx_geo + (($this->x_pix/$this->mapwidth) * $this->xdelta_geo); $y_geo = $this->maxy_geo - (($this->y_pix/$this->mapheight) * $this->ydelta_geo); $xyLayQueryList["x_geo"]= $x_geo; $xyLayQueryList["y_geo"]= $y_geo; if ($this->pointQuery) { $pixGeoSize = ($this->xdelta_geo/$this->mapwidth); $eAdd = 2; // search radius in map units $xyLayQueryList["xmin"] = round($x_geo - ($pixGeoSize * $eAdd)); $xyLayQueryList["ymin"] = round($y_geo - ($pixGeoSize * $eAdd)); $xyLayQueryList["xmax"] = round($x_geo + ($pixGeoSize * $eAdd)); $xyLayQueryList["ymax"] = round($y_geo + ($pixGeoSize * $eAdd)); } else { $xyLayQueryList["xmin"] = $this->minx_sel_geo; $xyLayQueryList["ymin"] = $this->miny_sel_geo; $xyLayQueryList["xmax"] = $this->maxx_sel_geo; $xyLayQueryList["ymax"] = $this->maxy_sel_geo; } $this->query = &new XYQuery($this->qLayer, $this->glayer, $xyLayQueryList, 0, $this->zoomFull); if ($this->mode == "nquery") { $resultlayers[$this->qLayerName] = $this->query->returnResultindexes(); $resulttilelayers[$this->qLayerName] = $this->query->returnResultTileindexes(); $this->Extents[] = $this->query->returnMaxExtent(); } if ($this->query) { $fieldHeaderStr = $this->query->getFieldHeaderStr($this->selHeaders); $this->colspan = count($this->selHeaders) + 1; } } /* * PRINT RESULTS FOR WMS LAYER **/ function q_printWMSLayer() { // Set map width, height and extent for use in WMS query $this->map->set("width", $this->mapwidth); $this->map->set("height", $this->mapheight); $this->map->setextent($this->minx_geo, $this->miny_geo, $this->maxx_geo, $this->maxy_geo); // Run query and print put results $this->query = new WMSQuery($grp, $this->qLayer, $this->x_pix, $this->y_pix ); $fieldHeaderStr = $this->query->getFieldHeaderStr($this->selHeaders); $this->colspan = $this->query->colspan; } /* * PROCESS ZOOM INFO AND SET RESULTLAYERS **/ function q_printZoomParameters() { $zp = "{"; // Get the maximum extent for more than 1 layer if 'autoZoom' or button 'zoomAll' selcted in config //print_r($this->Extents); if ($this->zoomFull && $this->numResultsTotal > 0) { //if (!is_array($this->Extents) ) { if (count($this->Extents) < 2) { $allExtStr = join("+", $this->Extents[0]); } else { $minx = $this->Extents[0][0]; $miny = $this->Extents[0][1]; $maxx = $this->Extents[0][2]; $maxy = $this->Extents[0][3]; for($i=1; $iExtents); $i++) { $minx = min($minx, $this->Extents[$i][0]); $miny = min($miny, $this->Extents[$i][1]); $maxx = max($maxx, $this->Extents[$i][2]); $maxy = max($maxy, $this->Extents[$i][3]); } $allExtStr = $minx .'+'. $miny .'+'. $maxx .'+'. $maxy; } } $zp .= "\"allextent\": \"$allExtStr\", "; // Add 'Zoom To All' button if 'zoomAll' selcted in config if ($this->doZoomAll && $this->numResultsTotal > 1) { $zp .= "\"zoomall\": true, "; } else { $zp .= "\"zoomall\": false, "; } // Message for more records found than limit set in ini file if ($this->numResultsTotal == $this->limitResult) { } // Autozoom to selected fatures if 'autoZoom' selcted in config if ($this->mode != "query" && $this->doAutoZoom && $this->numResultsTotal > 0) { $zp .= "\"autozoom\": \"auto\", "; // Re-load map frame to highlight selected features } elseif ($this->mode != "query" && $this->highlightSelected) { $zp .= "\"autozoom\": \"highlight\", "; } else { $zp .= "\"autozoom\": false, "; } $zp .= "\"infoWin\": \"". $_SESSION['infoWin'] ."\""; $zp .= "}"; // Register resultlayers for highlight in case of nquery (selection) if ($this->mode != "query" && $this->mode != "iquery" && $this->highlightSelected && $this->numResultsTotal > 0) { $_SESSION["resultlayers"] = $this->resultlayers; } //$this->allResStr .= $zStr; return $zp; } /* * RETURNS THE RESULT STRING (FROM VARABLE $qStr) *********************************************************************/ function getResultString() { return $this->qStr; } /* * RETURNS THE NUMBER OF RECORDS OF THE QUERY RESULT FOR A LAYER *********************************************************************/ function getLayNumResults() { return $this->numResults; } // Abstract methods: returnNumResults function setNumResults(){} function returnResultindexes() { return $this->resultindexes; } function returnResultTileindexes() { return $this->resulttileindexes; } /* Return maximum extent for all shapes found in query * used for NQUERY ********************************************************/ function returnMaxExtent() { $bufX = 0.05 *($this->mExtMaxx - $this->mExtMinx); $bufY = 0.05 *($this->mExtMaxy - $this->mExtMiny); $ExtMinx = $this->mExtMinx - $bufX; $ExtMiny = $this->mExtMiny - $bufY; $ExtMaxx = $this->mExtMaxx + $bufX; $ExtMaxy = $this->mExtMaxy + $bufY; if ($ExtMinx == $ExtMaxx || $ExtMiny == $ExtMaxy) { $ExtMinx = $ExtMinx - (abs($bufX * $ExtMinx)); $ExtMiny = $ExtMiny - (abs($bufY * $ExtMiny)); $ExtMaxx = $ExtMaxx + (abs($bufX * $ExtMaxx)); $ExtMaxy = $ExtMaxy + (abs($bufY * $ExtMaxy)); } $maxExtent = array($ExtMinx, $ExtMiny, $ExtMaxx, $ExtMaxy); return $maxExtent; } /* RESULT TABLE: FIELD HEADER * Print the table header for every single group/layer ************************************************************************/ function getFieldHeaderStr($selHeaders) { $slink = $this->qLayerType != 3 ? "@" : "#"; // TABLE HEADER: ATTRIBUTE NAMES... $pStr = "\"header\": [\"$slink\""; for ($iField=0; $iField < sizeof($selHeaders); $iField++) { $pStr .= ",\"" . $selHeaders[$iField] . "\""; } $pStr .= "], \"values\": [ "; return $pStr; } /* RESULT TABLE: FIELD VALUES * Print all field values (except shapeindex) for single layer ***********************************************************************/ function printFieldValues($fldName, $fldValue) { // Change format for decimal field values /* if (is_numeric($fldValue)) { if (preg_match('/\./', $fldValue)) { $fldValue = number_format($fldValue, 2, ',', ''); } } */ // !!!! ENCODE ALL STRINGS IN UTF-8 !!!! if ($this->layerEncoding) { if ($this->layerEncoding != "UTF-8") { $fldValue = iconv($this->layerEncoding, "UTF-8", $fldValue); } } else { $fldValue = utf8_encode($fldValue); } // Escape double quote sign //$fldValue = str_replace('"', '\\"', $fldValue); $fldValue = addslashes($fldValue); $valStr = ", "; $hyperFieldList = $this->glayer->getHyperFields(); $hyperFieldsValues = $hyperFieldList[0]; $hyperFieldsAlias = $hyperFieldList[1]; // Check for hyperlinks if (count($hyperFieldsValues) > 0) { if (in_array($fldName, $hyperFieldsValues)) { $valStr .= "{\"hyperlink\": [\"$this->qLayerName\",\"$fldName\",\"$fldValue\",\""; // Print ALIAS if defined if (strlen($hyperFieldsAlias[$fldName]) > 0) { $valStr .= $hyperFieldsAlias[$fldName]; // else field VALUE } else { $valStr .= $fldValue; } $valStr .= "\"]}"; } else { $valStr .= "\"$fldValue\""; } // NO hyperlink so just print normal output } else { $valStr .= "\"$fldValue\""; } return $valStr; } // Connect to DB with jointable, return connection handler function dbConnect($dsn) { $dbh = DB::connect($dsn); if (DB::isError($dbh)) { #die ($dbh->getMessage()); db_logErrors($dbh); return NULL; } else { return $dbh; } } /* * SEARCH VIA ATTRIBUTES ****************************************************************************/ function q_execAttributeQuery() { $this->qLayerName = $_GET["qlayer"]; $getvars = $_GET; // Return layer type $this->qLayer = $this->map->getLayerByName($this->qLayerName); $this->qLayerType = $this->qLayer->connectiontype; // Get group and glayer objects $GroupGlayer = returnGroupGlayer($this->qLayerName); $this->grp = $GroupGlayer[0]; $this->glayer = $GroupGlayer[1]; $this->XYLayerProperties = $this->glayer->getXYLayerProperties(); $this->layerEncoding = $this->glayer->getLayerEncoding(); // QUERY ON POSTGIS LAYER if ($this->qLayerType == 6 || $this->XYLayerProperties) { foreach ($getvars as $var => $val0) { if ($var != "PHPSESSID" && $var != "qlayer" && $var != "dbtable" && $var != "findlist" && $var != "mode") { $val = $this->q_strDecode($_GET["$var"]); if ($this->qLayerType == 6) { $varValStr = returnVar($var, $val, "postgis"); } else { $varValStr = returnVar($var, $val, "db"); //error_log("db"); } if (strlen(trim($val)) > 0) { $qStr .= $varValStr . " AND "; } } } $this->qStr = str_replace(';', ' 0 ERROR 0 ', substr($qStr, 0, -5)) ; //echo $this->qStr; // QUERY ON SHAPEFILE (ETC.) LAYER } else { $qStr = "("; // STANDARD QUERY foreach ($getvars as $var => $val0) { if ($var != "PHPSESSID" && $var != "qlayer" && $var != "dbtable" && $var != "findlist" && $var != "mode") { $fldName = preg_replace("/\#|\*/ie", "", $var); $val = $this->q_strDecode($_GET["$var"]); $varValStr = returnVar($var, $val, "shape"); if (strlen(trim($val)) > 0) { $qStr .= $varValStr . " AND "; } } } $qStr = substr($qStr, 0, strlen($qStr)-5) . ")"; //error_log("$fldName ---- $qStr"); @$this->qLayer->queryByAttributes($fldName, $qStr, MS_MULTIPLE); } } function q_printAttributeQuery() { $selHeaders = $this->grp->getResHeaders(); $this->colspan = count($selHeaders) + 1; // PROCESS QUERY DEPENDING ON LAYER TYPE if ($this->qLayerType == 6) { $this->query = new PGQuery($this->map, $this->qLayer, $this->glayer, $this->qStr, $this->zoomFull); } else { // Normal Layer if (!$this->XYLayerProperties) { $this->query = new DQuery($this->map, $this->qLayer, $this->glayer, $this->zoomFull); } else { //echo $this->qStr; $this->query = new XYQuery($this->qLayer, $this->glayer, $this->qStr, 1, $this->zoomFull); } } $this->layersResStr .= $this->query->getResultString(); $this->numResultsTotal += $this->query->getLayNumResults(); $this->fieldHeaderStr = $this->query->getFieldHeaderStr($selHeaders); if ($this->numResultsTotal > 0) { $this->resultlayers[$this->qLayerName] = $this->query->returnResultindexes(); $resulttilelayers[$this->qLayerName] = $this->query->returnResultTileindexes(); $_SESSION['resulttilelayers'] = $resulttilelayers; } $this->Extents[] = $this->query->returnMaxExtent(); $this->allResStr = "[ ["; $this->printGrpResString($this->grp); $zp = $this->q_printZoomParameters(); $this->allResStr .= "], $zp ]"; //echo "total : $this->numResultsTotal "; } function q_strDecode($inval) { // DECODE QUERY STRING FROM UTF-8 if ($this->layerEncoding) { if ($this->layerEncoding != "UTF-8") { return iconv("UTF-8", $this->layerEncoding, $inval); } else { return $inval; } } else { return utf8_decode($inval); } } /* * Test if layer has the same projection as map ***************************************************/ function checkProjection() { $mapProjStr = $this->map->getProjection(); $qLayerProjStr = $this->qLayer->getProjection(); if ($mapProjStr && $qLayerProjStr && $mapProjStr != $qLayerProjStr) { $changeLayProj = 1; $this->mapProjObj = ms_newprojectionobj($mapProjStr); $this->qLayerProjObj = ms_newprojectionobj($qLayerProjStr); } else { $changeLayProj = 0; } return $changeLayProj; } } // END CLASS /* * AUXILLIARY FUNCTION FOR ATTRIBUTE SEARCH * returns var and value; **************************************************/ function returnVar($var, $val, $datatype) { // CHAR Field if ($var{0} == "#") { // SEARCH WITH WILDCARD if ($var{1} == "*") { // Layertype = POSTGIS if ($datatype == "postgis") { $val = addslashes($val); $valStr = substr($var,2,strlen($var)-1) . " ~* '" . ($val{1} == "*" ? $val : "^". $val) . (substr($val,-1) == "*" ? "'" : "$'") ; $valStr = str_replace("\*", "", $valStr); // REMOVE WILDCARD * SIGN WITH ESCAPING \ FROM SEARCH STRING } elseif ($datatype == "db") { $val = addslashes($val); $varStr = "UPPER(" . strtolower(substr($var,2,strlen($var)-1)) . ") LIKE "; $valStr = "'" . str_replace("*", "%", strtoupper($val)) . "'"; } else { $varStr = "'[" . strtoupper(substr($var,2,strlen($var)-1)) . "]' =~ "; $val = preg_quote($val); $val = preg_replace("/[a-z]/ie", "'('. strtoupper(\\0) . '|' . strtolower(\\0) .')'", $val); // FOR CASE-INSENSITIVE QUERY $valStr = "/" . ($val{1} == "*" ? $val : "^". $val) . (substr($val,-1) == "*" ? "/" : "$/") ; $valStr = str_replace("\*", "", $valStr); // REMOVE WILDCARD * SIGN WITH ESCAPING \ FROM SEARCH STRING } // SEARCH WITHOUT WILDCARD } else { // Layertype = POSTGIS if ($datatype == "postgis") { $val = addslashes($val); $valStr = substr($var,1,strlen($var)-1) . " ~* '$val'"; } elseif ($datatype == "db") { $val = addslashes($val); $varStr = "UPPER(" . strtolower(substr($var,1,strlen($var)-1)) . ") LIKE "; $valStr = "'%" . strtoupper($val) . "%'"; } else { $varStr = "'[" . strtoupper(substr($var,1,strlen($var)-1)) . "]' =~ "; $val = preg_quote($val); $val = preg_replace ("/[a-z]/ie", "'('. strtoupper($0) . '|' . strtolower($0) .')'", $val); // FOR CASE-INSENSITIVE QUERY // FOR CASE-INSENSITIVE QUERY $valStr = "/" . $val . "/" ; } } return "$varStr $valStr"; // NUMERIC Field } else { // Layertype = POSTGIS if ($datatype == "postgis" || $datatype == "db") { $varStr = strtolower($var) . " = "; $valStr = $val ; } else { $varStr = "[" . strtoupper($var) . "] = "; $valStr = $val ; } return "$varStr $valStr"; } } ?>