Changeset 10380


Ignore:
Timestamp:
10/31/11 15:37:43 (13 years ago)
Author:
jschierm
Message:

Shp2Kml: Addition of polygon translation.

Location:
issm/trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/modules/Shp2Kmlx/Shp2Kmlx.cpp

    r10275 r10380  
    1212
    1313int Shp2Kmlx(char* filshp,char* filkml,
    14                          int sgn,
    15                          bool holes){
     14                         int sgn){
    1615
    1716        #ifdef _HAVE_SHAPELIB_ //only works if Shapelib library has been compiled in.
     
    2322
    2423        return(Shp2Kmlx(filshp,filkml,
    25                                         sgn,cm,sp,
    26                                         holes));
     24                                        sgn,cm,sp));
    2725
    2826        #endif //ifdef _HAVE_SHAPELIB_
     
    3028
    3129int Shp2Kmlx(char* filshp,char* filkml,
    32                          int sgn,double cm,double sp,
    33                          bool holes){
     30                         int sgn,double cm,double sp){
    3431
    3532        #ifdef _HAVE_SHAPELIB_ //only works if Shapelib library has been compiled in.
     
    3835        int     lwidth=1;
    3936        double  popac=0.50;
    40         int     nshap;
     37        int     nshape,ncoord;
     38        double  cpsum;
    4139        int     *pstype=NULL,*pnpart=NULL,**ppstrt=NULL,**pptype=NULL,*pnvert=NULL;
    4240        double  **pshapx=NULL,**pshapy=NULL,**pshapz=NULL,**pshapm=NULL;
    43         bool    *closed=NULL;
    4441        double  *lat=NULL,*lon=NULL;
    4542
     
    9794                        adfMaxBound[3] );
    9895
    99         nshap=nEntities;
    100         pstype=(int *) xmalloc(nshap*sizeof(int));
    101         pnpart=(int *) xmalloc(nshap*sizeof(int));
    102         ppstrt=(int **) xmalloc(nshap*sizeof(int *));
    103         pptype=(int **) xmalloc(nshap*sizeof(int *));
    104         pnvert=(int *) xmalloc(nshap*sizeof(int));
    105         pshapx=(double **) xmalloc(nshap*sizeof(double *));
    106         pshapy=(double **) xmalloc(nshap*sizeof(double *));
    107         pshapz=(double **) xmalloc(nshap*sizeof(double *));
    108         pshapm=(double **) xmalloc(nshap*sizeof(double *));
     96        nshape=nEntities;
     97        pstype=(int *) xmalloc(nshape*sizeof(int));
     98        pnpart=(int *) xmalloc(nshape*sizeof(int));
     99        ppstrt=(int **) xmalloc(nshape*sizeof(int *));
     100        pptype=(int **) xmalloc(nshape*sizeof(int *));
     101        pnvert=(int *) xmalloc(nshape*sizeof(int));
     102        pshapx=(double **) xmalloc(nshape*sizeof(double *));
     103        pshapy=(double **) xmalloc(nshape*sizeof(double *));
     104        pshapz=(double **) xmalloc(nshape*sizeof(double *));
     105        pshapm=(double **) xmalloc(nshape*sizeof(double *));
    109106
    110107/*  loop over the list of shapes  */
     
    206203
    207204        SHPClose( hSHP );
    208 
    209 /*  read exp file  */
    210 
    211 //      if (!DomainOutlineRead(&nshap,&pnvert,&pshapx,&pshapy,&closed,filshp,false))
    212 //              _error_("Error reading exp file.");
    213205
    214206/*  construct kml file  */
     
    273265/*  loop over the list of shapes  */
    274266
    275         for (i=0; i<nshap; i++) {
     267        for (i=0; i<nshape; i++) {
    276268
    277269/*  null type  */
     
    337329                        sprintf(kplace->styleurl  ,"#RandomLineEmptyPoly");
    338330
     331/*  create a multigeometry to hold all the lines  */
     332
    339333                        kmulti=new KML_MultiGeometry();
     334
     335/*  convert to lat/lon, if necessary  */
    340336
    341337                        lat=(double *) xmalloc(pnvert[i]*sizeof(double));
     
    348344                                memcpy(lat,pshapy[i],pnvert[i]*sizeof(double));
    349345                        }
     346
     347/*  loop over the lines  */
    350348
    351349                        for (j=0; j<pnpart[i]; j++) {
     
    378376                                 pstype[i] == SHPT_POLYGONZ ||
    379377                                 pstype[i] == SHPT_POLYGONM) {
    380                         _printf_(true,"Warning -- Shape %d of type \"%s\" will be ignored.\n",
    381                                          i,SHPTypeName( pstype[i] ));
    382                         continue;
    383 
    384 /*  polygon with multiple holes  */
    385 
    386         if (holes) {
    387                 i=0;
    388                 kplace=new KML_Placemark();
    389                 sprintf(kplace->name      ,"Polygon with Holes");
    390                 kplace->visibility=true;
    391                 sprintf(kplace->styleurl  ,"#BlackLineRandomPoly");
    392 
    393                 kpoly =new KML_Polygon();
    394                 kring =new KML_LinearRing();
    395 
    396                 lat=(double *) xmalloc(pnvert[i]*sizeof(double));
    397                 lon=(double *) xmalloc(pnvert[i]*sizeof(double));
    398                 Xy2llx(lat,lon,pshapx[i],pshapy[i],pnvert[i],sgn,cm,sp);
    399 
    400                 kring->ncoord    =pnvert[i];
    401                 kring->coords    =(double (*)[3]) xmalloc(pnvert[i]*3*sizeof(double));
    402                 for (j=0; j<pnvert[i]; j++) {
    403                         kring->coords[j][0]=lon[j];
    404                         kring->coords[j][1]=lat[j];
    405                         kring->coords[j][2]=0.;
    406                 }
    407                 xfree((void**)&lon);
    408                 xfree((void**)&lat);
    409 
    410                 (kpoly ->outer     )->AddObject((Object*)kring);
    411                 kring =NULL;
    412 
    413                 for (i=1; i<nshap; i++) {
    414                         if (!closed[i]) {
    415                                 _printf_(true,"Warning -- Inner profile %d is not closed with \"holes\" specified, so it will be ignored.\n",i+1);
    416                                 continue;
    417                         }
    418 
    419                         kring =new KML_LinearRing();
     378
     379/*  the shp format specifies that outer rings are cw, while inner rings are ccw.  there
     380        may be multiple outer rings and inner rings in any order.  the kml format specifies
     381        all rings are ccw (right-hand rule).  there may be only one outer ring with multiple
     382        inner rings, and rings are differentiated by keyword.
     383
     384        at least for now, assume that each cw ring forms a new kml polygon, and each ccw
     385        ring forms an inner ring for the most recent outer ring.  a more elaborate solution
     386        would be for each inner ring to search in which outer ring it occurs.  */
     387
     388                        kplace=new KML_Placemark();
     389
     390                        sprintf(kplace->name      ,"Shape:%d (%s)  nVertices=%d, nParts=%d",
     391                                        i,SHPTypeName(pstype[i]),pnvert[i],pnpart[i]);
     392                        kplace->visibility=true;
     393                        sprintf(kplace->styleurl  ,"#BlackLineRandomPoly");
     394
     395/*  create a multigeometry to hold all the polygons  */
     396
     397                        kmulti=new KML_MultiGeometry();
     398
     399/*  convert to lat/lon, if necessary  */
    420400
    421401                        lat=(double *) xmalloc(pnvert[i]*sizeof(double));
    422402                        lon=(double *) xmalloc(pnvert[i]*sizeof(double));
    423                         Xy2llx(lat,lon,pshapx[i],pshapy[i],pnvert[i],sgn,cm,sp);
    424                         kring->ncoord    =pnvert[i];
    425                         kring->coords    =(double (*)[3]) xmalloc(pnvert[i]*3*sizeof(double));
    426                         for (j=0; j<pnvert[i]; j++) {
    427                                 kring->coords[j][0]=lon[j];
    428                                 kring->coords[j][1]=lat[j];
    429                                 kring->coords[j][2]=0.;
    430                         }
     403                        if (sgn) {
     404                                Xy2llx(lat,lon,pshapx[i],pshapy[i],pnvert[i],sgn,cm,sp);
     405                        }
     406                        else  {
     407                                memcpy(lon,pshapx[i],pnvert[i]*sizeof(double));
     408                                memcpy(lat,pshapy[i],pnvert[i]*sizeof(double));
     409                        }
     410
     411/*  loop over the polygons  */
     412
     413                        for (j=0; j<pnpart[i]; j++) {
     414
     415/*  check if polygon is ccw or cw by computing sum of cross products (twice the area)  */
     416
     417                                ncoord=(j<pnpart[i]-1 ? ppstrt[i][j+1]-ppstrt[i][j] : pnvert[i]-ppstrt[i][j]);
     418                                cpsum =0.;
     419
     420                                for (k=ppstrt[i][j]; k<ppstrt[i][j]+ncoord-1; k++)
     421                                        cpsum +=pshapx[i][k]*pshapy[i][k+1         ]-pshapy[i][k]*pshapx[i][k+1         ];
     422                                cpsum +=pshapx[i][k]*pshapy[i][ppstrt[i][j]]-pshapy[i][k]*pshapx[i][ppstrt[i][j]];
     423
     424/*  outer ring (cw) (allow exception for single-part shapes)  */
     425
     426                                if (cpsum < 0 || pnpart[i] == 1) {
     427                                        if (kpoly) {
     428                                                (kmulti->geometry  )->AddObject((Object*)kpoly);
     429                                                kpoly =NULL;
     430                                        }
     431
     432/*  create a new polygon from the outer ring (reversing cw to ccw)  */
     433
     434                                        kpoly =new KML_Polygon();
     435                                        kring =new KML_LinearRing();
     436
     437                                        kring->ncoord    =(j<pnpart[i]-1 ? ppstrt[i][j+1]-ppstrt[i][j] : pnvert[i]-ppstrt[i][j]);
     438                                        kring->coords    =(double (*)[3]) xmalloc(kring->ncoord*3*sizeof(double));
     439                                        if (cpsum < 0)
     440                                                for (k=0; k<kring->ncoord; k++) {
     441                                                        kring->coords[kring->ncoord-1-k][0]=lon      [ppstrt[i][j]+k];
     442                                                        kring->coords[kring->ncoord-1-k][1]=lat      [ppstrt[i][j]+k];
     443                                                        kring->coords[kring->ncoord-1-k][2]=pshapz[i][ppstrt[i][j]+k];
     444                                                }
     445                                        else
     446                                                for (k=0; k<kring->ncoord; k++) {
     447                                                        kring->coords[k                ][0]=lon      [ppstrt[i][j]+k];
     448                                                        kring->coords[k                ][1]=lat      [ppstrt[i][j]+k];
     449                                                        kring->coords[k                ][2]=pshapz[i][ppstrt[i][j]+k];
     450                                                }
     451
     452                                        (kpoly ->outer     )->AddObject((Object*)kring);
     453                                        kring =NULL;
     454                                }
     455
     456/*  inner ring (ccw)  */
     457
     458                                else {
     459                                        if (!kpoly) {
     460                                                _printf_(true,"Warning -- Shape %d of type \"%s\", part %d, expected to be outer loop (cw).\n",
     461                                                                 i,SHPTypeName( pstype[i] ),j);
     462                                                continue;
     463                                        }
     464
     465/*  add the inner ring to the current polygon  */
     466
     467                                        kring =new KML_LinearRing();
     468
     469                                        kring->ncoord    =(j<pnpart[i]-1 ? ppstrt[i][j+1]-ppstrt[i][j] : pnvert[i]-ppstrt[i][j]);
     470                                        kring->coords    =(double (*)[3]) xmalloc(kring->ncoord*3*sizeof(double));
     471                                        for (k=0; k<kring->ncoord; k++) {
     472                                                kring->coords[k][0]=lon      [ppstrt[i][j]+k];
     473                                                kring->coords[k][1]=lat      [ppstrt[i][j]+k];
     474                                                kring->coords[k][2]=pshapz[i][ppstrt[i][j]+k];
     475                                        }
     476
     477                                        (kpoly ->inner     )->AddObject((Object*)kring);
     478                                        kring =NULL;
     479                                }
     480                        }
     481
     482                        if (kpoly) {
     483                                (kmulti->geometry  )->AddObject((Object*)kpoly);
     484                                kpoly =NULL;
     485                        }
     486
    431487                        xfree((void**)&lon);
    432488                        xfree((void**)&lat);
    433489
    434                         (kpoly ->inner     )->AddObject((Object*)kring);
    435                         kring =NULL;
    436                 }
    437 
    438                 (kplace->geometry  )->AddObject((Object*)kpoly);
    439                 kpoly =NULL;
    440                 (kfold ->feature   )->AddObject((Object*)kplace);
    441                 kplace=NULL;
    442         }
    443 
    444 /*  multiple polygons or linestrings  */
    445 
    446         else {
    447                 for (i=0; i<nshap; i++) {
    448                         kplace=new KML_Placemark();
    449 
    450                         if (closed[i]) {
    451                                 sprintf(kplace->name      ,"Polygon %d",i+1);
    452                                 kplace->visibility=true;
    453                                 sprintf(kplace->styleurl  ,"#BlackLineRandomPoly");
    454 
    455                                 kpoly =new KML_Polygon();
    456                                 kring =new KML_LinearRing();
    457 
    458                                 lat=(double *) xmalloc(pnvert[i]*sizeof(double));
    459                                 lon=(double *) xmalloc(pnvert[i]*sizeof(double));
    460                                 Xy2llx(lat,lon,pshapx[i],pshapy[i],pnvert[i],sgn,cm,sp);
    461 
    462                                 kring->ncoord    =pnvert[i];
    463                                 kring->coords    =(double (*)[3]) xmalloc(pnvert[i]*3*sizeof(double));
    464                                 for (j=0; j<pnvert[i]; j++) {
    465                                         kring->coords[j][0]=lon[j];
    466                                         kring->coords[j][1]=lat[j];
    467                                         kring->coords[j][2]=0.;
    468                                 }
    469                                 xfree((void**)&lon);
    470                                 xfree((void**)&lat);
    471 
    472                                 (kpoly ->outer     )->AddObject((Object*)kring);
    473                                 kring =NULL;
    474 
    475                                 (kplace->geometry  )->AddObject((Object*)kpoly);
    476                                 kpoly =NULL;
    477                         }
    478 
     490                        (kplace->geometry  )->AddObject((Object*)kmulti);
     491                        kmulti=NULL;
    479492                        (kfold ->feature   )->AddObject((Object*)kplace);
    480493                        kplace=NULL;
    481                 }
    482         }
    483494                }
    484495
     
    499510                                                 i,SHPTypeName( pstype[i] ),pnpart[i]);
    500511
     512/*  create a multigeometry to hold all the points  */
     513
    501514                        kmulti=new KML_MultiGeometry();
     515
     516/*  convert to lat/lon, if necessary  */
    502517
    503518                        lat=(double *) xmalloc(pnvert[i]*sizeof(double));
     
    511526                        }
    512527
     528/*  loop over the points  */
     529
    513530                        for (j=0; j<pnvert[i]; j++) {
    514531                                kpoint=new KML_Point();
     
    534551
    535552                else if (pstype[i] == SHPT_MULTIPATCH) {
     553                        _printf_(true,"Warning -- Shape %d of type \"%s\" will be ignored.\n",
     554                                         i,SHPTypeName( pstype[i] ));
     555                        continue;
    536556                }
    537557
     
    542562                                         i,SHPTypeName( pstype[i] ));
    543563                }
    544 
    545564        }
    546565
     
    561580
    562581        delete kfile;
    563         for (i=nshap-1; i>=0; i--) {
     582        for (i=nshape-1; i>=0; i--) {
    564583                xfree((void**)&(pshapm[i]));
    565584                xfree((void**)&(pshapz[i]));
     
    572591        xfree((void**)&pshapx);
    573592        xfree((void**)&pnvert);
    574         for (i=nshap-1; i>=0; i--) {
     593        for (i=nshape-1; i>=0; i--) {
    575594                xfree((void**)&(pptype[i]));
    576595                xfree((void**)&(ppstrt[i]));
  • issm/trunk/src/c/modules/Shp2Kmlx/Shp2Kmlx.h

    r10240 r10380  
    1212#endif
    1313
    14 #include <float.h>    /*  DBL_MAX  */
    15 
    1614#ifdef _HAVE_SHAPELIB_ //only works if Shapelib library has been compiled in.
    1715
     
    2523/* local prototypes: */
    2624int Shp2Kmlx(char* filshp,char* filkml,
    27                          int sgn,
    28                          bool holes);
     25                         int sgn);
    2926int Shp2Kmlx(char* filshp,char* filkml,
    30                          int sgn,double cm,double sp,
    31                          bool holes);
     27                         int sgn,double cm,double sp);
    3228
    3329#endif  /* _SHP2KMLX_H */
  • issm/trunk/src/mex/Shp2Kml/Shp2Kml.cpp

    r10239 r10380  
    2020
    2121        Options* options=NULL;
    22         char     *choles=NULL;
    23         bool     holes=false;
    2422        double   cm=0.,sp=0.;
    2523
     
    5654        options=new Options(NRHS,nrhs,prhs);
    5755        if (options->Size()) for(i=0;i<options->Size();i++) ((Option*)options->GetObjectByOffset(i))->DeepEcho();
    58         options->Get(&choles,"holes","no");
    59         if (!strncmp(choles,"y",1) || !strncmp(choles,"on",2))
    60                 holes=true;
    6156        /*  defaults are in Xy2lldef, so don't duplicate them here, and only use user values if both have been specified  */
    6257        if (options->GetOption("central_meridian") || options->GetOption("standard_parallel")) {
     
    7065        if (verbose) printf("Checking inputs:\n");
    7166
    72         if (sgn != +1 && sgn != -1) _error_("Hemisphere sgn=%d must be +1 (north) or -1 (south).",sgn);
     67//      if (sgn != +1 && sgn != -1) _error_("Hemisphere sgn=%d must be +1 (north) or -1 (south).",sgn);
    7368        if (fabs(cm)      > 180.) _error_("Central meridian cm=%g must be between -180 (west) and +180 (east) degrees.",cm);
    7469        if (sp < 0. || sp >  90.) _error_("Standard parallel sp=%g must be between 0 and 90 degrees (in specified hemisphere).",sp);
     
    7873        if (options->GetOption("central_meridian") && options->GetOption("standard_parallel"))
    7974                iret=Shp2Kmlx(filshp,filkml,
    80                                           sgn,cm,sp,
    81                                           holes);
     75                                          sgn,cm,sp);
    8276        else
    8377                iret=Shp2Kmlx(filshp,filkml,
    84                                           sgn,
    85                                           holes);
     78                                          sgn);
    8679        if (verbose) printf("  iret=%d\n",iret);
    8780
     
    9083
    9184        /*Clean-up*/
    92         xfree((void**)&choles);
    9385        delete options;
    9486        xfree((void**)&filkml);
     
    108100        _printf_(true,"      [ret]=Shp2Kml(filshp,filkml,sgn,'param name',param,...);\n");
    109101        _printf_(true,"\n");
    110         _printf_(true,"      filshp      file name of shp file to be read (char)\n");
     102        _printf_(true,"      filshp      file name of shp file to be read (char, extension optional)\n");
    111103        _printf_(true,"      filkml      file name of kml file to be written (char)\n");
    112         _printf_(true,"      sgn         sign for hemisphere (double, +1 (north) or -1 (south))\n");
     104        _printf_(true,"      sgn         sign for hemisphere (double, +1 (north); -1 (south); 0 (no translation))\n");
    113105        _printf_(true,"\n");
    114106        _printf_(true,"      central_meridian     central meridian (double, optional, but must specify with sp)\n");
    115107        _printf_(true,"      standard_parallel    standard parallel (double, optional, but must specify with cm)\n");
    116         _printf_(true,"      holes       flag for treatment of multiple profiles (char, optional, 'yes' for holes))\n");
    117108        _printf_(true,"\n");
    118109        _printf_(true,"      ret         return code (non-zero for warning)\n");
     
    120111        _printf_(true,"   Examples:\n");
    121112        _printf_(true,"      [ret]=Shp2Kml('file.shp','file.kml', 1);\n");
    122         _printf_(true,"      [ret]=Shp2Kml('file.shp','file.kml', 1,'central_meridian',45,'standard_parallel',70,'holes','yes');\n");
    123         _printf_(true,"      [ret]=Shp2Kml('file.shp','file.kml',-1,'central_meridian', 0,'standard_parallel',71,'holes','yes');\n");
     113        _printf_(true,"      [ret]=Shp2Kml('file.shp','file.kml', 1,'central_meridian',45,'standard_parallel',70,'holes');\n");
     114        _printf_(true,"      [ret]=Shp2Kml('file.shp','file.kml',-1,'central_meridian', 0,'standard_parallel',71,'holes');\n");
    124115        _printf_(true,"\n");
    125116}
Note: See TracChangeset for help on using the changeset viewer.