📄 shape2ogr.cpp
字号:
/****************************************************************************** * $Id: shape2ogr.cpp,v 1.32 2004/07/06 19:35:51 warmerda Exp $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements translation of Shapefile shapes into OGR * representation. * Author: Frank Warmerdam, warmerda@home.com * ****************************************************************************** * Copyright (c) 1999, Les Technologies SoftMap Inc. * * 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. ****************************************************************************** * * $Log: shape2ogr.cpp,v $ * Revision 1.32 2004/07/06 19:35:51 warmerda * Default to using FTString for unrecognised field types like logical. * * Revision 1.31 2004/01/16 22:40:40 warmerda * any inner rings not assigned to a polygo are promoted to be outer rings * * Revision 1.30 2003/12/11 19:19:40 warmerda * Fixed leak of geometry objects when building multipolygons. * * Revision 1.29 2003/11/09 18:54:53 warmerda * added auto-FID field creation if new file has no fields on first feature wrt * * Revision 1.28 2003/10/18 19:01:10 warmerda * added Radims patch to recognise multipolygons on read properly - bug 213 * * Revision 1.27 2003/06/10 14:44:11 warmerda * Added support for writing shapes with NULL geometries. * * Revision 1.26 2003/05/27 21:39:53 warmerda * added support for writing MULTILINESTRINGs as ARCs * * Revision 1.25 2003/05/21 04:03:54 warmerda * expand tabs * * Revision 1.24 2003/02/25 14:35:11 warmerda * Incorporated more correct support for reading multi-part arcs as * MultiLineStrings. * * Revision 1.23 2002/10/04 04:31:40 warmerda * Fixes for writing 3D multipoints. * * Revision 1.22 2002/10/04 04:30:46 warmerda * Fixed some bugs in 3D support for writing polygons. * * Revision 1.21 2002/08/15 15:10:01 warmerda * Fixed problem when GetFeature() called for a non-existant id. * http://bugzilla.remotesensing.org/show_bug.cgi?id=175 * * Revision 1.20 2002/08/14 23:27:25 warmerda * Fixed reading of Z coordinate for SHPT_ARCZ type. * * Revision 1.19 2002/04/17 21:49:02 warmerda * Fixed a bug writing arcs with Z coordinates. * * Revision 1.18 2002/04/17 20:03:27 warmerda * Try to preserve Z values on read. * * Revision 1.17 2002/04/17 20:01:39 warmerda * Ensure Z coordinate preserved on read. * * Revision 1.16 2002/04/16 16:21:28 warmerda * Ensure polygons written with correct winding. * * Revision 1.15 2002/03/27 21:04:38 warmerda * Added support for reading, and creating lone .dbf files for wkbNone geometry * layers. Added support for creating a single .shp file instead of a directory * if a path ending in .shp is passed to the data source create method. * * Revision 1.14 2001/12/06 18:14:22 warmerda * handle case where there is no DBF file * * Revision 1.13 2001/09/27 14:53:31 warmerda * added proper 3D support for all element types * * Revision 1.12 2001/09/04 15:39:07 warmerda * tightened up NULL attribute handling * * Revision 1.11 2001/07/18 04:55:16 warmerda * added CPL_CSVID * * Revision 1.10 2001/02/06 14:30:15 warmerda * don't crash on attempt to write geometryless features * * Revision 1.9 2000/11/29 14:09:36 warmerda * Extended shapefile OGR driver to support MULTIPOLYGON objects. * * Revision 1.8 2000/01/26 22:05:45 warmerda * fixed bug with 2d/3d arcs * * Revision 1.7 1999/12/23 14:51:07 warmerda * Improved support in face of 3D geometries. * * Revision 1.6 1999/11/04 21:18:01 warmerda * fix bug with shapeid for new shapes * * Revision 1.5 1999/07/27 01:52:04 warmerda * added support for writing polygon/multipoint/arc files * * Revision 1.4 1999/07/27 00:52:40 warmerda * added write methods * * Revision 1.3 1999/07/26 13:59:25 warmerda * added feature writing api * * Revision 1.2 1999/07/12 15:39:18 warmerda * added setting of shape geometry * * Revision 1.1 1999/07/05 18:58:07 warmerda * New * * Revision 1.3 1999/06/11 19:22:13 warmerda * added OGRFeature and OGRFeatureDefn related translation * * Revision 1.2 1999/05/31 20:41:49 warmerda * added multipoint support * * Revision 1.1 1999/05/31 19:26:03 warmerda * New */#include "ogrshape.h"#include "cpl_conv.h"CPL_CVSID("$Id: shape2ogr.cpp,v 1.32 2004/07/06 19:35:51 warmerda Exp $");/************************************************************************//* RingStartEnd *//* set first and last vertex for given ring *//************************************************************************/void RingStartEnd ( SHPObject *psShape, int ring, int *start, int *end ){ if( psShape->panPartStart == NULL ) { *start = 0; *end = psShape->nVertices - 1; } else { if( ring == psShape->nParts - 1 ) *end = psShape->nVertices - 1; else *end = psShape->panPartStart[ring+1] - 1; *start = psShape->panPartStart[ring]; }} /************************************************************************//* RingDirection() *//* *//* return: 1 CW (clockwise) *//* -1 CCW (counterclockwise) *//* 0 error *//************************************************************************/int RingDirection ( SHPObject *Shape, int ring ) { int i, start, end, v, next; double *x, *y, dx0, dy0, dx1, dy1, area2; /* Note: first and last coordinate MUST be identical according to shapefile specification */ if ( ring < 0 || ring >= Shape->nParts ) return ( 0 ); x = Shape->padfX; y = Shape->padfY; RingStartEnd ( Shape, ring, &start, &end ); /* Find the lowest rightmost vertex */ v = start; for ( i = start + 1; i < end; i++ ) { /* => v < end */ if ( y[i] < y[v] || ( y[i] == y[v] && x[i] > x[v] ) ) { v = i; } } /* Vertices may be duplicate, we have to go to nearest different in each direction */ /* preceding */ next = v - 1; while ( 1 ) { if ( next < start ) next = end - 1; if ( x[next] != x[v] || y[next] != y[v] ) break; if ( next == v ) /* So we cannot get into endless loop */ break; next--; } dx0 = x[next] - x[v]; dy0 = y[next] - y[v]; /* following */ next = v + 1; while ( 1 ) { if ( next >= end ) next = start; if ( x[next] != x[v] || y[next] != y[v] ) break; if ( next == v ) /* So we cannot get into endless loop */ break; next++; } dx1 = x[next] - x[v]; dy1 = y[next] - y[v]; area2 = dx1 * dy0 - dx0 * dy1; if ( area2 > 0 ) /* CCW */ return -1; else if ( area2 < 0 ) /* CW */ return 1; return 0; /* error */}/************************************************************************//* PointInRing() *//* *//* return: 1 point is inside the ring *//* 0 point is outside the ring *//* *//* for point exactly on the boundary it returns 0 or 1 *//************************************************************************/int PointInRing ( SHPObject *Shape, int ring, double x, double y ) { int i, start, end, c = 0; double *xp, *yp; if ( ring < 0 || ring >= Shape->nParts ) return ( 0 ); xp = Shape->padfX; yp = Shape->padfY; RingStartEnd ( Shape, ring, &start, &end ); /* This code was originaly written by Randolph Franklin, here it is slightly modified. */ for (i = start; i < end; i++) { if ( ( ( ( yp[i] <= y ) && ( y < yp[i+1] ) ) || ( ( yp[i+1] <= y ) && ( y < yp[i] ) ) ) && ( x < (xp[i+1] - xp[i]) * (y - yp[i]) / (yp[i+1] - yp[i]) + xp[i] ) ) { c = !c; } } return c;} /************************************************************************//* CreateLinearRing *//* *//************************************************************************/OGRLinearRing * CreateLinearRing ( SHPObject *psShape, int ring ){ OGRLinearRing *poRing; int nRingStart, nRingEnd, nRingPoints; poRing = new OGRLinearRing(); RingStartEnd ( psShape, ring, &nRingStart, &nRingEnd ); nRingPoints = nRingEnd - nRingStart + 1; poRing->setPoints( nRingPoints, psShape->padfX + nRingStart, psShape->padfY + nRingStart, psShape->padfZ + nRingStart ); return ( poRing );} /************************************************************************//* SHPReadOGRObject() *//* *//* Read an item in a shapefile, and translate to OGR geometry *//* representation. *//************************************************************************/OGRGeometry *SHPReadOGRObject( SHPHandle hSHP, int iShape ){ SHPObject *psShape; OGRGeometry *poOGR = NULL; psShape = SHPReadObject( hSHP, iShape ); if( psShape == NULL ) return NULL;/* -------------------------------------------------------------------- *//* Point. *//* -------------------------------------------------------------------- */ else if( psShape->nSHPType == SHPT_POINT || psShape->nSHPType == SHPT_POINTM || psShape->nSHPType == SHPT_POINTZ ) { poOGR = new OGRPoint( psShape->padfX[0], psShape->padfY[0], psShape->padfZ[0] ); }/* -------------------------------------------------------------------- *//* Multipoint. *//* -------------------------------------------------------------------- */ else if( psShape->nSHPType == SHPT_MULTIPOINT || psShape->nSHPType == SHPT_MULTIPOINTM || psShape->nSHPType == SHPT_MULTIPOINTZ ) { OGRMultiPoint *poOGRMPoint = new OGRMultiPoint(); int i; for( i = 0; i < psShape->nVertices; i++ ) { OGRPoint *poPoint; poPoint = new OGRPoint( psShape->padfX[i], psShape->padfY[i], psShape->padfZ[i] ); poOGRMPoint->addGeometry( poPoint ); delete poPoint; } poOGR = poOGRMPoint; }/* -------------------------------------------------------------------- *//* Arc (LineString) *//* *//* I am ignoring parts though they can apply to arcs as well. *//* -------------------------------------------------------------------- */ else if( psShape->nSHPType == SHPT_ARC || psShape->nSHPType == SHPT_ARCM || psShape->nSHPType == SHPT_ARCZ ) { if( psShape->nParts == 1 ) { OGRLineString *poOGRLine = new OGRLineString(); poOGRLine->setPoints( psShape->nVertices, psShape->padfX, psShape->padfY, psShape->padfZ ); poOGR = poOGRLine; } else { int iRing; OGRMultiLineString *poOGRMulti; poOGR = poOGRMulti = new OGRMultiLineString(); for( iRing = 0; iRing < psShape->nParts; iRing++ ) { OGRLineString *poLine; int nRingPoints; int nRingStart; poLine = new OGRLineString(); if( psShape->panPartStart == NULL ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -