Esempio n. 1
0
char *FLTGetSpatialComparisonCommonExpression(FilterEncodingNode *psNode, layerObj *lp)
{
  char *pszExpression = NULL;
  shapeObj *psQueryShape = NULL;
  double dfDistance = -1;
  int nUnit = -1, nLayerUnit = -1;
  char *pszWktText = NULL;
  char szBuffer[256];
  char *pszTmp=NULL;
  projectionObj sProjTmp;
  rectObj sQueryRect;
  shapeObj *psTmpShape=NULL;
  int bBBoxQuery = 0;
  int bAlreadyReprojected = 0;

  if (psNode == NULL || lp == NULL)
    return NULL;

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

  /* get the shape */
  if (FLTIsBBoxFilter(psNode)) {
    char szPolygon[512];
    FLTGetBBOX(psNode, &sQueryRect);

    snprintf(szPolygon, sizeof(szPolygon),
             "POLYGON((%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f,%.18f %.18f))",
             sQueryRect.minx, sQueryRect.miny,
             sQueryRect.minx, sQueryRect.maxy,
             sQueryRect.maxx, sQueryRect.maxy,
             sQueryRect.maxx, sQueryRect.miny,
             sQueryRect.minx, sQueryRect.miny);

    psTmpShape = msShapeFromWKT(szPolygon);

    /* 
    ** This is a horrible hack to deal with world-extent requests and
    ** reprojection. msProjectRect() detects if reprojection from longlat to 
    ** projected SRS, and in that case it transforms the bbox to -1e-15,-1e-15,1e15,1e15
    ** to ensure that all features are returned.
    **
    ** Make wfs_200_cite_filter_bbox_world.xml and wfs_200_cite_postgis_bbox_world.xml pass
    */
    if (fabs(sQueryRect.minx - -180.0) < 1e-5 &&
        fabs(sQueryRect.miny - -90.0) < 1e-5 &&
        fabs(sQueryRect.maxx - 180.0) < 1e-5 &&
        fabs(sQueryRect.maxy - 90.0) < 1e-5)
    {
      if (lp->projection.numargs > 0) {
        if (psNode->pszSRS)
          msInitProjection(&sProjTmp);
        if (psNode->pszSRS) {
          /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */
          if (msLoadProjectionString(&sProjTmp, psNode->pszSRS) == 0) {
            msProjectRect(&sProjTmp, &lp->projection, &sQueryRect);
          }
        } else if (lp->map->projection.numargs > 0)
          msProjectRect(&lp->map->projection, &lp->projection, &sQueryRect);
        if (psNode->pszSRS)
          msFreeProjection(&sProjTmp);
      }
      if (sQueryRect.minx <= -1e14) {
        msFreeShape(psTmpShape);
        msFree(psTmpShape);
        psTmpShape = (shapeObj*) msSmallMalloc(sizeof(shapeObj));
        msInitShape(psTmpShape);
        msRectToPolygon(sQueryRect, psTmpShape);
        bAlreadyReprojected = 1;
      }
    }

    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) {
      nLayerUnit = lp->units;
      if(nLayerUnit == -1) nLayerUnit = GetMapserverUnitUsingProj(&lp->projection);
      if(nLayerUnit == -1) nLayerUnit = lp->map->units;
      if(nLayerUnit == -1) nLayerUnit = GetMapserverUnitUsingProj(&lp->map->projection);

      if (nUnit >= 0 && nUnit != nLayerUnit)
        dfDistance *= msInchesPerUnit(nUnit,0)/msInchesPerUnit(nLayerUnit,0); /* target is layer units */
    }

    psTmpShape = psQueryShape;
  }

  if (psTmpShape) {

    /*
    ** target is layer projection
    */
    if (!bAlreadyReprojected && lp->projection.numargs > 0) {
      if (psNode->pszSRS)
        msInitProjection(&sProjTmp);
      if (psNode->pszSRS) {
        /* Use the non EPSG variant since axis swapping is done in FLTDoAxisSwappingIfNecessary */
        if (msLoadProjectionString(&sProjTmp, psNode->pszSRS) == 0) {
          msProjectShape(&sProjTmp, &lp->projection, psTmpShape);
        }
      } else if (lp->map->projection.numargs > 0)
        msProjectShape(&lp->map->projection, &lp->projection, psTmpShape);
      if (psNode->pszSRS)
        msFreeProjection(&sProjTmp);
    }

    /* function name */
    if (bBBoxQuery) {
      sprintf(szBuffer, "%s", "intersects");
    } else {
      if (strncasecmp(psNode->pszValue, "intersect", 9) == 0)
        sprintf(szBuffer, "%s", "intersects");
      else {
        pszTmp = msStrdup(psNode->pszValue);
        msStringToLower(pszTmp);
        sprintf(szBuffer, "%s", pszTmp);
        msFree(pszTmp);
      }
    }
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    pszExpression = msStringConcatenate(pszExpression, "(");

    /* geometry binding */
    sprintf(szBuffer, "%s", "[shape]");
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    pszExpression = msStringConcatenate(pszExpression, ",");

    /* filter geometry */
    pszWktText = msGEOSShapeToWKT(psTmpShape);
    sprintf(szBuffer, "%s", "fromText('");
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    pszExpression = msStringConcatenate(pszExpression, pszWktText);
    sprintf(szBuffer, "%s", "')");
    pszExpression = msStringConcatenate(pszExpression, szBuffer);
    msGEOSFreeWKT(pszWktText);

    /* (optional) beyond/dwithin distance, always 0.0 since we apply the distance as a buffer earlier */
    if ((strcasecmp(psNode->pszValue, "DWithin") == 0 || strcasecmp(psNode->pszValue, "Beyond") == 0)) {
      // pszExpression = msStringConcatenate(pszExpression, ",0.0");
      sprintf(szBuffer, ",%g", dfDistance);
      pszExpression = msStringConcatenate(pszExpression, szBuffer);      
    }

    /* terminate the function */
    pszExpression = msStringConcatenate(pszExpression, ") = TRUE");
  }

  /*
  ** Cleanup
  */
  if (bBBoxQuery) {
    msFreeShape(psTmpShape);
    msFree(psTmpShape);
  }

  return pszExpression;
}
Esempio n. 2
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;
}