/** * Author : GĂ©rald FENOY * * Copyright 2008-2009 GeoLabs SARL. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "cpl_conv.h" #include "ogr_api.h" #include "ogr_geometry.h" #include "geos_c.h" #include "service.h" #include "service_internal.h" extern "C" { #include #include #include #include #include #include #include #include #include void printExceptionReportResponse(maps*,map*); char *base64(const char *input, int length); OGRGeometryH createGeometryFromGML(maps* conf,char* inputStr){ xmlInitParser(); xmlDocPtr doc = xmlParseMemory(inputStr,strlen(inputStr)); xmlChar *xmlbuff; int buffersize; xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; char * xpathExpr="/*/*/*/*/*[local-name()='Polygon' or local-name()='MultiPolygon']"; xpathCtx = xmlXPathNewContext(doc); xpathObj = xmlXPathEvalExpression(BAD_CAST xpathExpr,xpathCtx); if(!xpathObj->nodesetval){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse Input Polygon")); setMapInMaps(conf,"lenv","code","InvalidParameterValue"); return NULL; } int size = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0; /** * Create a temporary XML document */ xmlDocPtr ndoc = xmlNewDoc(BAD_CAST "1.0"); /** * Only one polygon should be provided so we use it as the root node. */ for(int k=size-1;k>=0;k--){ xmlDocSetRootElement(ndoc, xpathObj->nodesetval->nodeTab[k]); } xmlDocDumpFormatMemory(ndoc, &xmlbuff, &buffersize, 1); char *tmp=(char*)calloc((xmlStrlen(xmlStrstr(xmlbuff,BAD_CAST "?>"))-1),sizeof(char)); sprintf(tmp,"%s",xmlStrstr(xmlbuff,BAD_CAST "?>")+2); xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); xmlFree(xmlbuff); xmlFreeDoc(doc); xmlFreeDoc(ndoc); #ifndef WIN32 xmlCleanupParser(); #endif #ifdef DEBUG fprintf(stderr,"\nService internal print\n Loading the geometry from GML string ..."); #endif OGRGeometryH res=OGR_G_CreateFromGML(tmp); free(tmp); if(res==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to call OGR_G_CreatFromGML")); return NULL; } else return res; } #ifdef WIN32 __declspec(dllexport) #endif int Simplify(maps*& conf,maps*& inputs,maps*& outputs){ maps* cursor=inputs; OGRGeometryH geometry,res; double tolerance; map* tmp0=getMapFromMaps(cursor,"Tolerance","value"); if(tmp0==NULL){ tolerance=atof("2.0"); } else tolerance=atof(tmp0->value); #ifdef DEBUG fprintf(stderr,"Tolerance for Simplify %f",tolerance); #endif map* tmp=getMapFromMaps(inputs,"InputPolygon","value"); if(!tmp){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon")); return SERVICE_FAILED; } map* tmp1=getMapFromMaps(inputs,"InputPolygon","mimeType"); if(tmp1!=NULL){ if(strncmp(tmp1->value,"text/js",7)==0 || strncmp(tmp1->value,"application/json",16)==0) geometry=OGR_G_CreateGeometryFromJson(tmp->value); else geometry=createGeometryFromGML(conf,tmp->value); } else{ setMapInMaps(conf,"lenv","message",_ss("Unable to find any geometry for InputPolygon")); return SERVICE_FAILED; } if(geometry==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon")); return SERVICE_FAILED; } #ifdef DEBUG fprintf(stderr,"Create GEOSGeometry object"); #endif GEOSGeometry* ggeometry=((OGRGeometry *) geometry)->exportToGEOS(); GEOSGeometry* gres=GEOSTopologyPreserveSimplify(ggeometry,tolerance); res=(OGRGeometryH)OGRGeometryFactory::createFromGEOS(gres); tmp1=getMapFromMaps(outputs,"Result","mimeType"); if(tmp1!=NULL){ if(strncmp(tmp1->value,"text/js",7)==0 || strncmp(tmp1->value,"application/json",16)==0){ char *tmpS=OGR_G_ExportToJson(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/plain"); setMapInMaps(outputs,"Result","encoding","UTF-8"); free(tmpS); #endif } else{ char *tmpS=OGR_G_ExportToGML(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/xml"); setMapInMaps(outputs,"Result","encoding","UTF-8"); setMapInMaps(outputs,"Result","schema","http://fooa/gml/3.1.0/polygon.xsd"); free(tmpS); #endif } }else{ char *tmpS=OGR_G_ExportToJson(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/plain"); setMapInMaps(outputs,"Result","encoding","UTF-8"); free(tmpS); #endif } outputs->next=NULL; //GEOSFree(ggeometry); //GEOSFree(gres); OGR_G_DestroyGeometry(res); OGR_G_DestroyGeometry(geometry); return SERVICE_SUCCEEDED; } int applyOne(maps*& conf,maps*& inputs,maps*& outputs,OGRGeometryH (*myFunc)(OGRGeometryH),char* schema){ #ifdef DEBUG fprintf(stderr,"\nService internal print\n"); #endif maps* cursor=inputs; OGRGeometryH geometry,res; #ifdef DEBUG dumpMaps(cursor); #endif map* tmp=getMapFromMaps(inputs,"InputPolygon","value"); if(!tmp){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon")); return SERVICE_FAILED; } #ifdef DEBUG fprintf(stderr,"Service internal print \n"); dumpMaps(inputs); fprintf(stderr,"/Service internal print \n"); #endif map* tmp1=getMapFromMaps(inputs,"InputPolygon","mimeType"); #ifdef DEBUG fprintf(stderr,"Service internal print \n"); dumpMap(tmp1); fprintf(stderr,"/Service internal print \n"); #endif if(tmp1!=NULL){ if(strncmp(tmp1->value,"text/js",7)==0 || strncmp(tmp1->value,"application/json",7)==0) geometry=OGR_G_CreateGeometryFromJson(tmp->value); else geometry=createGeometryFromGML(conf,tmp->value); } else geometry=createGeometryFromGML(conf,tmp->value); if(geometry==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse the input geometry from InputPolygon")); return SERVICE_FAILED; } res=(*myFunc)(geometry); #ifdef DEBUG fprintf(stderr,"Service internal print \n"); dumpMaps(outputs); fprintf(stderr,"/Service internal print \n"); #endif map *tmp_2=getMapFromMaps(outputs,"Result","mimeType"); #ifdef DEBUG fprintf(stderr,"Service internal print \n"); dumpMap(tmp_2); fprintf(stderr,"/Service internal print \n"); #endif if(tmp_2!=NULL){ if(strncmp(tmp_2->value,"text/js",7)==0 || strncmp(tmp_2->value,"application/json",16)==0){ char *tmpS=OGR_G_ExportToJson(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/plain"); setMapInMaps(outputs,"Result","encoding","UTF-8"); free(tmpS); #endif } else{ char *tmpS=OGR_G_ExportToGML(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/xml"); setMapInMaps(outputs,"Result","encoding","UTF-8"); setMapInMaps(outputs,"Result","schema",schema); free(tmpS); #endif } }else{ char *tmpS=OGR_G_ExportToJson(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/plain"); setMapInMaps(outputs,"Result","encoding","UTF-8"); free(tmpS); #endif } //outputs->next=NULL; #ifdef DEBUG dumpMaps(outputs); fprintf(stderr,"\nService internal print\n===\n"); #endif OGR_G_DestroyGeometry(res); OGR_G_DestroyGeometry(geometry); //CPLFree(res); //CPLFree(geometry); #ifdef DEBUG fprintf(stderr,"Service internal print \n"); dumpMaps(outputs); fprintf(stderr,"/Service internal print \n"); #endif return SERVICE_SUCCEEDED; } #ifdef WIN32 __declspec(dllexport) #endif int Buffer(maps*& conf,maps*& inputs,maps*& outputs){ OGRGeometryH geometry,res; map* tmp=getMapFromMaps(inputs,"InputPolygon","value"); if(tmp==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to fetch input geometry")); return SERVICE_FAILED; }else if(strlen(tmp->value)<=0){ setMapInMaps(conf,"lenv","message",_ss("Unable to fetch input geometry")); return SERVICE_FAILED; } map* tmp1=getMapFromMaps(inputs,"InputPolygon","mimeType"); if(strncmp(tmp1->value,"application/json",16)==0) geometry=OGR_G_CreateGeometryFromJson(tmp->value); else geometry=createGeometryFromGML(conf,tmp->value); if(geometry==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry")); return SERVICE_FAILED; } double bufferDistance; tmp=getMapFromMaps(inputs,"BufferDistance","value"); if(tmp==NULL){ bufferDistance=atof("10.0"); } else bufferDistance=atof(tmp->value); res=OGR_G_Buffer(geometry,bufferDistance,30); dumpMap(tmp); tmp1=getMapFromMaps(outputs,"Result","mimeType"); dumpMap(tmp); if(strncmp(tmp1->value,"application/json",16)==0){ char *tmpS=OGR_G_ExportToJson(res); setMapInMaps(outputs,"Result","value",tmpS); dumpMap(tmp); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/plain"); setMapInMaps(outputs,"Result","encoding","UTF-8"); free(tmpS); #endif } else{ char *tmpS=OGR_G_ExportToGML(res); setMapInMaps(outputs,"Result","value",tmpS); dumpMap(tmp); #ifndef WIN32 free(tmpS); setMapInMaps(outputs,"Result","mimeType","text/xml"); setMapInMaps(outputs,"Result","encoding","UTF-8"); setMapInMaps(outputs,"Result","schema","http://fooa/gml/3.1.0/polygon.xsd"); #endif } //outputs->next=NULL; OGR_G_DestroyGeometry(geometry); OGR_G_DestroyGeometry(res); return SERVICE_SUCCEEDED; } #ifdef WIN32 __declspec(dllexport) #endif int Boundary(maps*& conf,maps*& inputs,maps*& outputs){ return applyOne(conf,inputs,outputs,&OGR_G_GetBoundary,"http://fooa/gml/3.1.0/polygon.xsd"); } #ifdef WIN32 __declspec(dllexport) #endif int ConvexHull(maps*& conf,maps*& inputs,maps*& outputs){ return applyOne(conf,inputs,outputs,&OGR_G_ConvexHull,"http://fooa/gml/3.1.0/polygon.xsd"); } OGRGeometryH MY_OGR_G_Centroid(OGRGeometryH hTarget){ OGRGeometryH res; res=OGR_G_CreateGeometryFromJson("{\"type\": \"Point\", \"coordinates\": [0,0] }"); OGRwkbGeometryType gtype=OGR_G_GetGeometryType(hTarget); if(gtype!=wkbPolygon){ hTarget=OGR_G_ConvexHull(hTarget); } int c=OGR_G_Centroid(hTarget,res); return res; } #ifdef WIN32 __declspec(dllexport) #endif int Centroid(maps*& conf,maps*& inputs,maps*& outputs){ return applyOne(conf,inputs,outputs,&MY_OGR_G_Centroid,"http://fooa/gml/3.1.0/point.xsd"); } int applyTwo(maps*& conf,maps*& inputs,maps*& outputs,OGRGeometryH (*myFunc)(OGRGeometryH,OGRGeometryH)){ #ifdef DEBUG fprintf(stderr,"\nService internal print1\n"); fflush(stderr); fprintf(stderr,"\nService internal print1\n"); dumpMaps(inputs); fprintf(stderr,"\nService internal print1\n"); #endif maps* cursor=inputs; OGRGeometryH geometry1,geometry2; OGRGeometryH res; { map* tmp=getMapFromMaps(inputs,"InputEntity1","value"); map* tmp1=getMapFromMaps(inputs,"InputEntity1","mimeType"); if(tmp1!=NULL){ if(strncmp(tmp1->value,"application/json",16)==0) geometry1=OGR_G_CreateGeometryFromJson(tmp->value); else geometry1=createGeometryFromGML(conf,tmp->value); } else geometry1=createGeometryFromGML(conf,tmp->value); } if(geometry1==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry for InputEntity1.")); #ifdef DEBUG fprintf(stderr,"SERVICE FAILED !\n"); #endif return SERVICE_FAILED; } #ifdef DEBUG fprintf(stderr,"\nService internal print1 InputEntity1\n"); #endif { map* tmp=getMapFromMaps(inputs,"InputEntity2","value"); map* tmp1=getMapFromMaps(inputs,"InputEntity2","mimeType"); #ifdef DEBUG fprintf(stderr,"MY MAP \n[%s] - %i\n",tmp1->value,strncmp(tmp1->value,"application/json",16)); //dumpMap(tmp); fprintf(stderr,"MY MAP\n"); fprintf(stderr,"\nService internal print1 InputEntity2\n"); #endif if(tmp1!=NULL){ if(strncmp(tmp1->value,"application/json",16)==0){ #ifdef DEBUG fprintf(stderr,"\nService internal print1 InputEntity2 as JSON\n"); #endif geometry2=OGR_G_CreateGeometryFromJson(tmp->value); } else{ #ifdef DEBUG fprintf(stderr,"\nService internal print1 InputEntity2 as GML\n"); #endif geometry2=createGeometryFromGML(conf,tmp->value); } } else geometry2=createGeometryFromGML(conf,tmp->value); #ifdef DEBUG fprintf(stderr,"\nService internal print1 InputEntity2 PreFinal\n"); #endif } #ifdef DEBUG fprintf(stderr,"\nService internal print1 InputEntity2 Final\n"); #endif if(geometry2==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry for InputEntity2.")); #ifdef DEBUG fprintf(stderr,"SERVICE FAILED !\n"); #endif return SERVICE_FAILED; } #ifdef DEBUG fprintf(stderr,"\nService internal print1\n"); #endif res=(*myFunc)(geometry1,geometry2); #ifdef DEBUG fprintf(stderr,"\nService internal print1\n"); #endif /* nuova parte */ map* tmp2=getMapFromMaps(outputs,"Result","mimeType"); if(strncmp(tmp2->value,"application/json",16)==0){ char *tmpS=OGR_G_ExportToJson(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/plain"); setMapInMaps(outputs,"Result","encoding","UTF-8"); free(tmpS); #endif } else{ char *tmpS=OGR_G_ExportToGML(res); setMapInMaps(outputs,"Result","value",tmpS); #ifndef WIN32 setMapInMaps(outputs,"Result","mimeType","text/xml"); setMapInMaps(outputs,"Result","encoding","UTF-8"); setMapInMaps(outputs,"Result","schema","http://fooa/gml/3.1.0/polygon.xsd"); free(tmpS); #endif } /* vecchia da togliere */ /* char *tmpS=OGR_G_ExportToJson(res); setMapInMaps(outputs,"Result","value",tmpS); setMapInMaps(outputs,"Result","mimeType","text/plain"); setMapInMaps(outputs,"Result","encoding","UTF-8"); free(tmpS); */ OGR_G_DestroyGeometry(geometry1); OGR_G_DestroyGeometry(geometry2); OGR_G_DestroyGeometry(res); return SERVICE_SUCCEEDED; } #ifdef WIN32 __declspec(dllexport) #endif int Difference(maps*& conf,maps*& inputs,maps*& outputs){ return applyTwo(conf,inputs,outputs,&OGR_G_Difference); } #ifdef WIN32 __declspec(dllexport) #endif int SymDifference(maps*& conf,maps*& inputs,maps*& outputs){ return applyTwo(conf,inputs,outputs,&OGR_G_SymmetricDifference); } #ifdef WIN32 __declspec(dllexport) #endif int Intersection(maps*& conf,maps*& inputs,maps*& outputs){ return applyTwo(conf,inputs,outputs,&OGR_G_Intersection); } #ifdef WIN32 __declspec(dllexport) #endif int Union(maps*& conf,maps*& inputs,maps*& outputs){ return applyTwo(conf,inputs,outputs,&OGR_G_Union); } #ifdef WIN32 __declspec(dllexport) #endif int Distance(maps*& conf,maps*& inputs,maps*& outputs){ #ifdef DEBUG fprintf(stderr,"\nService internal print1\n"); #endif fflush(stderr); maps* cursor=inputs; OGRGeometryH geometry1,geometry2; double res; { map* tmp=getMapFromMaps(inputs,"InputEntity1","value"); map* tmp1=getMapFromMaps(inputs,"InputEntity1","mimeType"); #ifdef DEBUG fprintf(stderr,"MY MAP\n"); dumpMap(tmp1); dumpMaps(inputs); fprintf(stderr,"MY MAP\n"); #endif if(tmp1!=NULL){ if(strncmp(tmp1->value,"application/json",16)==0) geometry1=OGR_G_CreateGeometryFromJson(tmp->value); else geometry1=createGeometryFromGML(conf,tmp->value); } else geometry1=createGeometryFromGML(conf,tmp->value); } if(geometry1==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry for InputEntity1.")); fprintf(stderr,"SERVICE FAILED !\n"); return SERVICE_FAILED; } { map* tmp=getMapFromMaps(inputs,"InputEntity2","value"); map* tmp1=getMapFromMaps(inputs,"InputEntity2","mimeType"); #ifdef DEBUG fprintf(stderr,"MY MAP\n"); dumpMap(tmp1); dumpMaps(inputs); fprintf(stderr,"MY MAP\n"); #endif if(tmp1!=NULL){ if(strncmp(tmp1->value,"application/json",16)==0) geometry2=OGR_G_CreateGeometryFromJson(tmp->value); else geometry2=createGeometryFromGML(conf,tmp->value); } else geometry2=createGeometryFromGML(conf,tmp->value); } if(geometry2==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry for InputEntity2.")); fprintf(stderr,"SERVICE FAILED !\n"); return SERVICE_FAILED; } res=OGR_G_Distance(geometry1,geometry2); char tmpres[100]; sprintf(tmpres,"%f",res); setMapInMaps(outputs,"Distance","value",tmpres); setMapInMaps(outputs,"Distance","dataType","float"); #ifdef DEBUG dumpMaps(outputs); fprintf(stderr,"\nService internal print\n===\n"); #endif return SERVICE_SUCCEEDED; } #ifdef WIN32 __declspec(dllexport) #endif int GetArea(maps*& conf,maps*& inputs,maps*& outputs){ fprintf(stderr,"GETAREA \n"); double res; /** * Extract Geometry from the InputPolygon value */ OGRGeometryH geometry; map* tmp=getMapFromMaps(inputs,"InputPolygon","value"); if(tmp==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry from InputPolygon")); return SERVICE_FAILED; } fprintf(stderr,"geometry creation %s \n",tmp->value); geometry=createGeometryFromGML(conf,tmp->value); if(geometry==NULL){ setMapInMaps(conf,"lenv","message",_ss("Unable to parse input geometry from InputPolygon")); return SERVICE_FAILED; } fprintf(stderr,"geometry created %s \n",tmp->value); res=OGR_G_GetArea(geometry); fprintf(stderr,"area %d \n",res); /** * Filling the outputs */ char tmp1[100]; sprintf(tmp1,"%f",res); setMapInMaps(outputs,"Area","value",tmp1); setMapInMaps(outputs,"Area","dataType","float"); #ifdef DEBUG dumpMaps(outputs); #endif return SERVICE_SUCCEEDED; } }