Need help with Layer->QueryByPoint

Camden Daily cdaily at GMAIL.COM
Mon Apr 4 12:31:50 EDT 2005


I don't believe that would fix things.  The issue is with mapserver
not having access to set the 'index' value for the shapes you're
adding in.  With no index values, queryByPoint won't work at all.

See the bug report on it at
http://mapserver.gis.umn.edu/bugs/show_bug.cgi?id=806

It's been fixed in the CVS version apparently, but for now, try
grabbing the modified version of the php_mapscript.c file linked on
the bug report and use it to recompile mapscript (v 4.4.1).  You
should then be able to do $shape->set("index", $index).

Just FYI, the indexes you set can not be arbitrarily assigned.  They
must be set in the same order that they are added to a layer, starting
with 0 and incrementing by 1.  Otherwise, queryByPoint() won't work.
Hence, I would start with an empty layer, so that you know to start
your indexing at 0.

On Apr 4, 2005 11:20 AM, Jeff Portwine <jdport at veritime.com> wrote:
> Thanks a lot for the response... that should get me going in the right
> direction.
> As for the bug you mentioned, can I work around that by simply adding the
> layer to my map file and then opening it and adding the points via
> mapscript?    That way the layer isn't actually generated by mapscript, it's
> only edited by mapscript... or would that cause the same problem?
>
> Thanks again!
>
> -Jeff
>
> ----- Original Message -----
> From: "Camden Daily" <cdaily at GMAIL.COM>
> To: <MAPSERVER-USERS at LISTS.UMN.EDU>
> Sent: Monday, April 04, 2005 11:09 AM
> Subject: Re: [UMN_MAPSERVER-USERS] Need help with Layer->QueryByPoint
>
> > Jeff,
> >
> > The first issue you're going to hit is a bug in mapscript that makes
> > the queryByPoint function useless against layers generated by
> > mapscript.  There's a fix in the CVS version of the code, but for now
> > just search the listserv archives for the terms 'queryByPoint' and
> > 'index' to find some other threads regarding that bug.
> >
> > As for queryByPoint, here's a function I wrote for getting the closest
> > points from a layer.  It may be overkill for your situation, but at
> > least it should demonstrate how queryByPoint works. It will return
> > multiple results in an array sorted by distance from the queried
> > point.  It also reprojects the points to a projection that uses meters
> > as units so that I can calculate a distance of miles instead of DD or
> > whatever.
> >
> > Before you can query the layer, you'll need to set a template value
> > for your layer.  This doesn't need to be a real template, just
> > something to keep mapserver from complaining.  Just do something like
> > $layer->set("template", "dummy").
> >
> > function get_closest($layer, $longitude, $latitude, $min_number_results) {
> >  global $map, $meter_to_mile;
> >
> >  // create a new point object to test against
> >  $point = ms_newPointObj();
> >  $point->setXY($longitude, $latitude);
> >
> >  $layer = $map->getLayerByName($layer);
> >
> >  // toleranceunits do not need to be in the same units as the projections
> >  $layer->set("toleranceunits", MS_MILES);
> >
> >  // loop through, increasing our search radius by 1 mile each time
> > until we find some matches
> >  $tolerance = 1;
> >  $max_tolerance = 30;  // won't search for points further than 30 miles
> > away
> >  $found_flag = false;
> >  while (!$found_flag AND ($tolerance < $max_tolerance)) {
> >    $layer->set("tolerance", $tolerance);
> >    $layer->queryByPoint($point, MS_MULTIPLE, -1);
> >    $num_results = $layer->getNumResults();
> >    if ($num_results >= $min_number_results) {
> >      $found_flag = true; }
> >    else {
> >      $tolerance++; }
> >  }
> >
> >  // if no results, return -1 to signify an error
> >  if ($num_results == 0) {
> >    return -1; }
> >
> >  else {
> >    // clone the point
> >    $temp_point = ms_newPointObj();
> >    $temp_point->setXY($point->x, $point->y);
> >
> >    // project cloned point to NAD83 / Illinois East so that our
> > calculated distance are in meters, not dd
> >    $temp_point->project(ms_newprojectionobj("init=epsg:4326"),
> > ms_newprojectionobj("init=epsg:26971"));
> >
> >    // loop through our results and add them to our return array
> >    $layer->open();
> >    for ($i=0; $i < $num_results; $i++) {
> >      $result = $layer->getResult($i);
> >      $shape = $layer->getShape($result->tileindex, $result->shapeindex);
> >      // reproject our shape to the same projection as our cloned point
> >      $shape->project(ms_newprojectionobj("init=epsg:4326"),
> > ms_newprojectionobj("init=epsg:26971"));
> >      $distance = $temp_point->distanceToShape($shape);
> >      $distance = round($distance * $meter_to_mile, 2);
> >      // add the data to our array
> >      $return[$i]['distance'] = $distance;
> >      $return[$i]['shape'] = $shape;
> >    }
> >    $layer->close();
> >
> >    // sort our multidimensional array on 'distance'
> >    foreach ($return as $val) {
> >      $sortarray[] = $val['distance']; }
> >    array_multisort($sortarray, $return);
> >
> >    return $return;
> >  }
> > }
> >
>
>



More information about the mapserver-users mailing list