addXY($x,$y); } $shape->add($line); # This adds the line with all the coordinates from the CGI #$shape->setBounds(); # This initalizes the shape. # Search a map for the shapes # Set up the query to perform the select, with the buffer and all! # If the Map does not open correctly, error out. $queryMap = ms_newMapObj($selectMap) or appError('Could not open mapfile: '.$selectMap."\n".'Please verify the Map file is valid.'); # This section of code searches for the query layer. # If a layer is not the query layer, it is turned off so that errorneous/extraneous results are not # also returned. This also helps speed queries so that multiple large datasets are not simultaneously queried. $queryLayerFound = false; # Set an error condition in case we do not find the layer for($l = 0; $l < $queryMap->{numlayers}; $l++) { $queryLayer = $queryMap->getLayer($l); $queryLayer->set('status', MS_OFF); # Turn the layer off if($queryLayer->{name} == $selectLayer) { # If it's the layer we're trying to search... $queryLayer->set('status',MS_ON); # Turn it on! $queryLayerFound = true; # "Unset" the Error Condition } } if(!$queryLayerFound) { # If they layer is not found in the mapfile, error out. appError("The Query Layer '$selectLayer' could not be found in the mapfile ($selectMap)."); } # Perform the Query. $queryResultCheck = $queryMap->queryByShape($shape); if($queryResultCheck == MS_FAILURE) { # If the query fails, error out. # Check to see if the Map has any pointers to an empty file $empty = $queryMap->web->empty; # If it's set then show that HTML instead. :D if(isset($empty) and $empty != '') { readfile($empty); exit(0); } else { appError('Query Failed to return any results!'); } } $queryResultShape = null; $shapesToBuffer = getShapesFromLayer($queryMap, $selectLayer, $shape); if(sizeof($shapesToBuffer) < 0) { appError('Failed to select any shapes from layer: '.$selectLayer); } $queryResultShape = false; for($s = 0; $s < sizeof($shapesToBuffer); $s++) { # for($fl = 0; $fl < $shapesToBuffer[$s]->numlines; $fl++) { # $queryResultShape->add($shapesToBuffer[$s]->line($fl)); # } if($queryResultShape) { $queryResultShape = $queryResultShape->union_geos($shapesToBuffer[$s]); } else { $queryResultShape = $shapesToBuffer[$s]; } } #print $shapesToBuffer[0]->toWKT(); if(isset($buffer)) { # This is a bit of a hack, but allows for the selection to work for # lines and points. if($buffer == 0) { $buffer = .0001; } # Mapscript using GEOS to bufffer the queryResultShape $queryResultShape = $queryResultShape->buffer($buffer); # Check to make sure the function returned a valid queryResultShape, if not, error. if(!isset($queryResultShape)) { appError("Buffering Failed. Buffer size: $buffer. Verify mapscript was linked with GEOS and that the buffer is a positive-real number."); } } $resultShapes = getShapesFromLayer($queryMap, $qLayer, $queryResultShape); $shape = $queryResultShape; $resultContents = array(); $queryLayerObj = $queryMap->getLayerByName($qLayer); $resultsShapeType = -1; # Get the layer type and set it $layerType = $queryLayerObj->{type}; $drawLayer = 'SelectedPolygon'; if($layerType == MS_LAYER_POINT) { $resultsShapeType = MS_SHP_POINT; $drawLayer = 'SelectedPoint'; } else { # Assume it's a polygon, eh? Okay. $resultsShapeType = MS_SHP_POLYGON; } # Process the query template from the mapfile and return it to the user # This way the results are displayed exactly as they are definied in the mapfile. $queryMap->getLayerByName($selectLayer)->set('status',MS_OFF); $queryMap->getLayerByName($qLayer)->set('status',MS_ON); $queryMap->queryByShape($shape); $template = $queryMap->processQueryTemplate(array(), array()); $template = str_replace('[QUERY_ID]', $id,$template); # Get the "selected" list $queryColumns = array(); # Hash table to hold the column names. $queryLayerObj->queryByShape($shape); $queryLayerObj->open(); # Open the layer for operation. for($item = 0; $item < $queryLayerObj->{numitems}; $item++) { $queryColumns{$queryLayerObj->getItem($item)} = $item; } if($queryLayerObj->getNumResults() > 0) { # Check to make sure we have SOME results for($result = 0; $result < $queryLayerObj->getNumResults(); $result++) { $queryResult = $queryLayerObj->getResult($result); # Get the feature from that result. # I left getFeature in here, as getShape will be deprecated for getFeature #$queryFeature = $queryLayerObj->getFeature($queryResult->{shapeindex}, $queryResult->{tileindex}); $queryFeature = $queryLayerObj->getShape($queryResult->{tileindex}, $queryResult->{shapeindex}); # Here's where the array from before becomes very handy. The column *name* is passed # into the CGI, so we need to result the shapefile-column index and the name, # which is query %queryColumns does! So now, we can just pull the ID column from the object. $v = $queryFeature->{values}[$queryColumn]; # And put that ID onto the stack of results... array_push($resultContents, $v); } } $queryLayerObj->close(); # Close the layer # Create a new Coordinate string based on any potential buffering. # This is needed because after the object has been buffered it will have a new coordinate string. # This information is passed back to the GeoMOOSE client so that it can set the "mapshape" parameter # which displays the layer highlighting. $coordString = ''; for($line = 0; $line < $shape->{numlines}; $line++) { $lineObj = $shape->line($line); for($point = 0; $point < $lineObj->{numpoints}; $point++) { $pointObj = $lineObj->point($point); $coordString = $coordString.$pointObj->{x}.' '.$pointObj->{y}.' '; } } # Store some useful information in a Shapefile # # Create the shapefile from the selection area # # Create the necessary dbase files... $selectionId = $id.'_selection'; $bufferedSelectionId = $id.'_buffered'; # Write out the selection shape writeShapeFile($TEMP_DIRECTORY.'/'.$id, MS_SHP_POLYGON, array($shape), 'selection'); # And the shapes selected from the selection shapes #print 'N shapes: '.sizeof($resultShapes); writeShapeFile($TEMP_DIRECTORY.'/'.$selectionId, $resultsShapeType, $resultShapes, 'shape'); # And the resulting shapes writeShapeFile($TEMP_DIRECTORY.'/'.$bufferedSelectionId, $shapeFileType, $shapesToBuffer,'buffered_selection'); # Create a Mapfile for displaying the correct information $mapfileTemplate = file_get_contents($DRAWING_MAP); $majorKeys = array(); $majorKeys['TEMPDIR'] = $TEMP_DIRECTORY; # Tells the mapfile where the shapes are stored $majorKeys['ID'] = $id; $majorKeys['SELECTIONID'] = $selectionId; $majorKeys['BUFFEREDSELECTIONID'] = $bufferedSelectionId; foreach($majorKeys as $key=>$value) { $mapfileTemplate = str_replace('%'.$key.'%', $value, $mapfileTemplate); } $outputMapfileName = $TEMP_DIRECTORY.'/'.$id.'.map'; $outputMapfile = fopen($outputMapfileName, "w"); fputs($outputMapfile, $mapfileTemplate); fclose($outputMapfile); $activeLayers = array($drawLayer, 'BufferedSelection', 'SelectedArea'); # Give the client the ID back so it can reference it later if($output == 'xml') { header('Content-type: text/xml'); # Return the XML that tells GeoMOOSE what to do! # # By passing "mapbook fragments" back to GeoMOOSE we can change the behavior and # definition of the maps being displayed. $layer contains the mapbook name of the # layer we were selecting-against. The "" line will set the mapshape parameter for # the layer we selected against. print ""; print ""; print ""; printf("", $layer); print " $DRAWING_MAP"; print " "; for($i = 0; $i < count($activeLayers); $i++) { printf("", $activeLayers[$i], $i); } # # print ""; # This takes the ID's from the results stack and puts it inside the layer. foreach ($resultContents as $id) { # print "\t\t\n"; printf(" ", $id); } print "\t"; print ""; # Print some header information. print ''; print '
'; print " "; print '
'; print $template; print "
"; # End the XML Page. } elseif($output == 'html') { header('Content-type: text/html'); ## HTML OUTPUT # This is a HTML/XML trick that uses XML namespaces in order to embed a GeoMOOSE # mapbook into a HTML document. print ''; print "\n"; print "\n"; print ""; # print "\n"; printf("\n"); printf(" %s", $outputMapfileName); #$DRAWING_MAP); printf(" ", $id); printf(" ", $selectionId); printf(" ", $bufferedSelectionId); for($i = 0; $i < count($activeLayers); $i++) { printf("", $activeLayers[$i], $i); } foreach ($resultContents as $id) { printf(" \n", $id); } print "\n"; print "\n"; print ""; print ""; print ""; print ""; print ""; } else { appError('Unrecognized output option: '.$output); } ?>