Пример #1
0
static shapeObj *msGEOSGeometry2Shape_multipolygon(GEOSGeom g)
{
  int i, j, k;
  shapeObj *shape=NULL;
  lineObj line;
  int numPoints, numRings, numPolygons;

  GEOSCoordSeq coords;
  GEOSGeom polygon, ring;

  if(!g) return NULL;
  numPolygons = GEOSGetNumGeometries(g);

  shape = (shapeObj *) malloc(sizeof(shapeObj));
  msInitShape(shape);
  shape->type = MS_SHAPE_POLYGON;
  shape->geometry = (GEOSGeom) g;

  for(k=0; k<numPolygons; k++) { /* for each polygon */
    polygon = (GEOSGeom) GEOSGetGeometryN(g, k);

    /* exterior ring */
    ring = (GEOSGeom) GEOSGetExteriorRing(polygon);
    numPoints = GEOSGetNumCoordinates(ring);
    coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring);

    line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints);
    line.numpoints = numPoints;

    for(i=0; i<numPoints; i++) {
	  GEOSCoordSeq_getX(coords, i, &(line.point[i].x));
      GEOSCoordSeq_getY(coords, i, &(line.point[i].y));
      /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */
    }
    msAddLineDirectly(shape, &line);
    
    /* interior rings */
    numRings = GEOSGetNumInteriorRings(polygon);

    for(j=0; j<numRings; j++) {
      ring = (GEOSGeom) GEOSGetInteriorRingN(polygon, j);
      if(GEOSisRing(ring) != 1) continue; /* skip it */      

      numPoints = GEOSGetNumCoordinates(ring);
      coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring);	  

      line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints);
      line.numpoints = numPoints;

      for(i=0; i<numPoints; i++) {
	GEOSCoordSeq_getX(coords, i, &(line.point[i].x));
        GEOSCoordSeq_getY(coords, i, &(line.point[i].y));
        /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */
      }
      msAddLineDirectly(shape, &line);	  
    }
  } /* next polygon */

  msComputeBounds(shape); 

  return shape; 
}
Пример #2
0
XShape::XShape(shapefileObj *shpfile, int i, int label_field)
  :label(NULL)
{
#ifdef ENABLE_OPENGL
  for (unsigned l=0; l < THINNING_LEVELS; l++)
    index_count[l] = indices[l] = NULL;
#endif

  shapeObj shape;
  msInitShape(&shape);
  msSHPReadShape(shpfile->hSHP, i, &shape);

  bounds = GeoBounds(GeoPoint(Angle::Degrees(fixed(shape.bounds.minx)),
                              Angle::Degrees(fixed(shape.bounds.maxy))),
                     GeoPoint(Angle::Degrees(fixed(shape.bounds.maxx)),
                              Angle::Degrees(fixed(shape.bounds.miny))));

#ifdef ENABLE_OPENGL
  center = bounds.GetCenter();
#endif

  type = shape.type;

  num_lines = 0;

  const int min_points = min_points_for_type(shape.type);
  if (min_points < 0) {
    /* not supported, leave an empty XShape object */
    points = NULL;
    msFreeShape(&shape);
    return;
  }

  const unsigned input_lines = std::min((unsigned)shape.numlines,
                                        (unsigned)MAX_LINES);
  unsigned num_points = 0;
  for (unsigned l = 0; l < input_lines; ++l) {
    if (shape.line[l].numpoints < min_points)
      /* malformed shape */
      continue;

    lines[num_lines] = std::min(shape.line[l].numpoints, 16384);
    num_points += lines[num_lines];
    ++num_lines;
  }

#ifdef ENABLE_OPENGL
  /* OpenGL:
   * Convert all points of all lines to ShapePoints, using a projection
   * that assumes the center of the screen is also the center of the shape.
   * Resolution is set to 1m per pixel. This enables us to use a simple matrix
   * multiplication to draw the shape.
   * This approximation should work well with shapes of limited size
   * (<< 400km). Perceivable distortion will only happen, when the latitude of
   * the actual center of the screen is far away from the latitude of the
   * center of the shape and the shape has a big vertical size.
   */

  points = new ShapePoint[num_points];
  ShapePoint *p = points;
#else // !ENABLE_OPENGL
  /* convert all points of all lines to GeoPoints */

  points = new GeoPoint[num_points];
  GeoPoint *p = points;
#endif
  for (unsigned l = 0; l < num_lines; ++l) {
    const pointObj *src = shape.line[l].point;
    num_points = lines[l];
    for (unsigned j = 0; j < num_points; ++j, ++src)
#ifdef ENABLE_OPENGL
      *p++ = geo_to_shape(GeoPoint(Angle::Degrees(fixed(src->x)),
                                   Angle::Degrees(fixed(src->y))));
#else
      *p++ = GeoPoint(Angle::Degrees(fixed(src->x)),
                      Angle::Degrees(fixed(src->y)));
#endif
  }

  if (label_field >= 0) {
    const char *src = msDBFReadStringAttribute(shpfile->hDBF, i, label_field);
    label = import_label(src);
  }

  msFreeShape(&shape);
}
Пример #3
0
char *FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, layerObj *lp)
{
    char *pszExpression = NULL;
    shapeObj *psQueryShape = NULL;
    double dfDistance = -1;
    int nUnit = -1;
    char *pszWktText = NULL;
    char szBuffer[256];
    char *pszTmp=NULL;
    projectionObj sProjTmp;
    char *pszEPSG= NULL;
    rectObj sQueryRect;
    shapeObj *psTmpShape=NULL, *psBufferShape=NULL;
    int bBBoxQuery = 0;
    
    if (psNode == NULL || lp == NULL)
      return NULL;

    if (psNode->eType != FILTER_NODE_TYPE_SPATIAL)
      return NULL;

    /* get the shape*/
    /*BBOX case: replace it with NOT DISJOINT.*/
    if(FLTIsBBoxFilter(psNode))
    {
        pszEPSG = FLTGetBBOX(psNode, &sQueryRect);
        /*this should be removed and bbox should parse and strore the srs properly, 
          using now legacy code*/
        if (pszEPSG)
          psNode->pszSRS = msStrdup(pszEPSG);
        
        psTmpShape = (shapeObj *)msSmallMalloc(sizeof(shapeObj));
        msInitShape(psTmpShape);
        msRectToPolygon(sQueryRect, psTmpShape);
        bBBoxQuery = 1;

    }
    else
    {
        /*other geos type operations*/

        /*project shape to layer projection. If the proj is not part of the filter query,
          assume that the cooredinates are in the map projection*/
      
        psQueryShape = FLTGetShape(psNode, &dfDistance, &nUnit);
    
        if ((strcasecmp(psNode->pszValue, "DWithin") == 0 ||
             strcasecmp(psNode->pszValue, "Beyond") == 0 ) &&
            dfDistance > 0)
        {
            if (nUnit >=0 && nUnit != lp->map->units)
              dfDistance *= msInchesPerUnit(nUnit,0)/msInchesPerUnit(lp->map->units,0);

            psBufferShape = msGEOSBuffer(psQueryShape, dfDistance);
        }
        if (psBufferShape)
          psTmpShape = psBufferShape;
        else
          psTmpShape = psQueryShape;
    }

    if (psTmpShape)
    {
        if( lp->projection.numargs > 0)
        {
            if (psNode->pszSRS && FTLParseEpsgString(psNode->pszSRS, &sProjTmp))
            {
              msProjectShape(&sProjTmp, &lp->projection, psTmpShape);
              msFreeProjection(&sProjTmp);
            }
            else if (lp->map->projection.numargs > 0)
              msProjectShape(&lp->map->projection, &lp->projection, psTmpShape);
        }
/* ==================================================================== */
/*      use within for bbox. Not Disjoint does not work.                */
/* ==================================================================== */
        if (bBBoxQuery)
          sprintf(szBuffer, "%s", " ([shape] ");
        /* sprintf(szBuffer, "%s", " (NOT ([shape] "); */
        else
          sprintf(szBuffer, "%s", " ([shape] ");

        pszExpression = msStringConcatenate(pszExpression, szBuffer);


        if (strncasecmp(psNode->pszValue, "intersect", 9) == 0)
          pszTmp = msStrdup("intersects");
        else
          pszTmp = msStrdup(psNode->pszValue);
        msStringToLower(pszTmp);
        if (bBBoxQuery)
          sprintf(szBuffer, " %s ", "intersects");
        /* sprintf(szBuffer, " %s ", "disjoint"); */
        else
           sprintf(szBuffer, " %s ", pszTmp);

        pszExpression = msStringConcatenate(pszExpression, szBuffer);
        msFree(pszTmp);

        pszWktText = msGEOSShapeToWKT(psTmpShape);
        sprintf(szBuffer, "%s", " fromText('");
        pszExpression = msStringConcatenate(pszExpression, szBuffer);
        pszExpression = msStringConcatenate(pszExpression, pszWktText);
        sprintf(szBuffer, "%s", "')");
        pszExpression = msStringConcatenate(pszExpression, szBuffer);
        msGEOSFreeWKT(pszWktText);
    }
    if (psBufferShape)
      msFreeShape(psBufferShape);

    
    sprintf(szBuffer, "%s", ")");
    pszExpression = msStringConcatenate(pszExpression, szBuffer);

    if (0) /* bBBoxQuery */
     {
          sprintf(szBuffer, "%s", ")");
          pszExpression = msStringConcatenate(pszExpression, szBuffer);
     }
    return pszExpression;
}
Пример #4
0
static int
msProjectRectAsPolygon(projectionObj *in, projectionObj *out,
                       rectObj *rect)
{
#ifdef USE_PROJ
  shapeObj polygonObj;
  lineObj  ring;
  /*  pointObj ringPoints[NUMBER_OF_SAMPLE_POINTS*4+4]; */
  pointObj *ringPoints;
  int     ix, iy;

  double dx, dy;

  /* If projecting from longlat to projected */
  if( out && !pj_is_latlong(out->proj) && in && pj_is_latlong(in->proj) &&
      fabs(rect->minx - -180.0) < 1e-5 && fabs(rect->miny - -90.0) < 1e-5 &&
      fabs(rect->maxx - 180.0) < 1e-5 && fabs(rect->maxy - 90.0) < 1e-5) {
    rect->minx = -1e15;
    rect->miny = -1e15;
    rect->maxx = 1e15;
    rect->maxy = 1e15;
    return MS_SUCCESS;
  }

  /* -------------------------------------------------------------------- */
  /*      Build polygon as steps around the source rectangle.             */
  /* -------------------------------------------------------------------- */
  dx = (rect->maxx - rect->minx)/NUMBER_OF_SAMPLE_POINTS;
  dy = (rect->maxy - rect->miny)/NUMBER_OF_SAMPLE_POINTS;

  if(dx==0 && dy==0) {
    pointObj foo;
    msDebug( "msProjectRect(): Warning: degenerate rect {%f,%f,%f,%f}\n",rect->minx,rect->miny,rect->minx,rect->miny );
    foo.x = rect->minx;
    foo.y = rect->miny;
    msProjectPoint(in,out,&foo);
    rect->minx=rect->maxx=foo.x;
    rect->miny=rect->maxy=foo.y;
    return MS_SUCCESS;
  }
  
  ringPoints = (pointObj*) calloc(sizeof(pointObj),NUMBER_OF_SAMPLE_POINTS*4+4);
  ring.point = ringPoints;
  ring.numpoints = 0;

  msInitShape( &polygonObj );
  polygonObj.type = MS_SHAPE_POLYGON;

  /* sample along top */
  if(dx != 0) {
    for(ix = 0; ix <= NUMBER_OF_SAMPLE_POINTS; ix++ ) {
      ringPoints[ring.numpoints].x = rect->minx + ix * dx;
      ringPoints[ring.numpoints++].y = rect->miny;
    }
  }

  /* sample on along right side */
  if(dy != 0) {
    for(iy = 1; iy <= NUMBER_OF_SAMPLE_POINTS; iy++ ) {
      ringPoints[ring.numpoints].x = rect->maxx;
      ringPoints[ring.numpoints++].y = rect->miny + iy * dy;
    }
  }

  /* sample along bottom */
  if(dx != 0) {
    for(ix = NUMBER_OF_SAMPLE_POINTS-1; ix >= 0; ix-- ) {
      ringPoints[ring.numpoints].x = rect->minx + ix * dx;
      ringPoints[ring.numpoints++].y = rect->maxy;
    }
  }

  /* sample on along left side */
  if(dy != 0) {
    for(iy = NUMBER_OF_SAMPLE_POINTS-1; iy >= 0; iy-- ) {
      ringPoints[ring.numpoints].x = rect->minx;
      ringPoints[ring.numpoints++].y = rect->miny + iy * dy;
    }
  }

  msAddLineDirectly( &polygonObj, &ring );

  /* -------------------------------------------------------------------- */
  /*      Attempt to reproject.                                           */
  /* -------------------------------------------------------------------- */
  msProjectShapeLine( in, out, &polygonObj, 0 );

  /* If no points reprojected, try a grid sampling */
  if( polygonObj.numlines == 0 || polygonObj.line[0].numpoints == 0 ) {
    msFreeShape( &polygonObj );
    return msProjectRectGrid( in, out, rect );
  }

  /* -------------------------------------------------------------------- */
  /*      Collect bounds.                                                 */
  /* -------------------------------------------------------------------- */
  rect->minx = rect->maxx = polygonObj.line[0].point[0].x;
  rect->miny = rect->maxy = polygonObj.line[0].point[0].y;

  for( ix = 1; ix < polygonObj.line[0].numpoints; ix++ ) {
    pointObj  *pnt = polygonObj.line[0].point + ix;

    rect->minx = MS_MIN(rect->minx,pnt->x);
    rect->maxx = MS_MAX(rect->maxx,pnt->x);
    rect->miny = MS_MIN(rect->miny,pnt->y);
    rect->maxy = MS_MAX(rect->maxy,pnt->y);
  }

  msFreeShape( &polygonObj );

  /* -------------------------------------------------------------------- */
  /*      Special case to handle reprojection from "more than the         */
  /*      whole world" projected coordinates that sometimes produce a     */
  /*      region greater than 360 degrees wide due to various wrapping    */
  /*      logic.                                                          */
  /* -------------------------------------------------------------------- */
  if( out && pj_is_latlong(out->proj) && in && !pj_is_latlong(in->proj)
      && rect->maxx - rect->minx > 360.0 ) {
    rect->maxx = 180;
    rect->minx = -180;
  }

  return MS_SUCCESS;
#else
  msSetError(MS_PROJERR, "Projection support is not available.", "msProjectRect()");
  return(MS_FAILURE);
#endif
}