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($queryMapFile) or appError('Could not open mapfile: '.$queryMapFile."\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 ($queryMapFile)."); } # 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); $queryResultShape = ms_newShapeObj(MS_SHAPE_POLYGON); for($s = 0; $s < sizeof($shapesToBuffer); $s++) { for($fl = 0; $fl < $shapesToBuffer[$s]->numlines; $fl++) { $queryResultShape->add($shapesToBuffer[$s]->line($fl)); } } if(isset($buffer)) { # 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()); # 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($directory.'/'.$id, MS_SHP_POLYGON, array($shape), 'selection'); # And the shapes selected from the selection shapes #print 'N shapes: '.sizeof($resultShapes); writeShapeFile($directory.'/'.$selectionId, $resultsShapeType, $resultShapes, 'shape'); # And the resulting shapes writeShapeFile($directory.'/'.$bufferedSelectionId, $shapeFileType, $shapesToBuffer,'buffered_selection'); # 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 " $drawingMapFile"; print " "; print " "; 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", $drawingMapFile); printf(" ", $id); printf(" ", $selectionId); printf(" ", $bufferedSelectionId); print " "; foreach ($resultContents as $id) { printf(" \n", $id); } print "\n"; print "\n"; print ""; print ""; print $template; print ""; print ""; } else { appError('Unrecognized output option: '.$output); } function appError($msg) { print ""; print "GeoMOOSE Buffered Select Error"; print ""; print "

Selection Service Message

"; print "".$msg.""; print ""; print ""; exit(0); } function writeShapeFile($shapeFileName, $shapeFileType, $shapes, $class) { $fields = array( array("class", "C", 32) ); $shapefile = ms_newShapefileObj($shapeFileName, $shapeFileType); if(!isset($shapefile)) { appError("Cannot Open Shapefile! ".$shapeFileName.".shp\n"); } $dbaseFilename = $shapeFileName.'.dbf'; if(!dbase_create($dbaseFilename, $fields)) { appError('Could not create dbase file: '.$shapeFileName); } $dbase = dbase_open($dbaseFilename, 2); foreach ($shapes as $shape) { dbase_add_record($dbase, array($class)); $shapefile->addShape($shape); } dbase_close($dbase); $shapefile->free(); } function getShapesFromLayer($map, $layerName, $searchShape) { $shapes = array(); # New array to hold results $map->getLayerByName($layerName)->set('status',MS_ON); $map->queryByShape($searchShape); # Query the map by the search shape for($l = 0; $l < $map->{numlayers}; $l++) { # Cycle through the layers $layer = $map->getLayer($l); # Get they layer object from the map. if($layer->{name} == $layerName or $layerName == '*') { # Check to make sure it's our layer of interest. $layer->open(); # Open the layer for operation. if($layer->getNumResults() > 0) { # Check to make sure we have SOME results for($result = 0; $result < $layer->getNumResults(); $result++) { # Get the member of the result set $queryResult = $layer->getResult($result); # Get the feature from that result. $queryFeature = $layer->getShape($queryResult->{tileindex}, $queryResult->{shapeindex}); array_push($shapes, $queryFeature); } } $layer->close(); # Close the layer } } return $shapes; } ?>