Changeset 12091
- Timestamp:
- 09/06/07 20:20:20 (1 year ago)
- Files:
-
- trunk/gdal/ogr/ogrsf_frmts/kml/GNUmakefile (modified) (2 diffs)
- trunk/gdal/ogr/ogrsf_frmts/kml/kml.cpp (added)
- trunk/gdal/ogr/ogrsf_frmts/kml/kml.h (added)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlfeature.cpp (deleted)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlfeatureclass.cpp (deleted)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlnode.cpp (added)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlnode.h (added)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlreader.h (deleted)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlutility.h (added)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlvector.cpp (added)
- trunk/gdal/ogr/ogrsf_frmts/kml/kmlvector.h (added)
- trunk/gdal/ogr/ogrsf_frmts/kml/makefile.vc (modified) (2 diffs)
- trunk/gdal/ogr/ogrsf_frmts/kml/ogr2kmlgeometry.cpp (modified) (2 diffs)
- trunk/gdal/ogr/ogrsf_frmts/kml/ogr_kml.h (modified) (10 diffs)
- trunk/gdal/ogr/ogrsf_frmts/kml/ogrkmldatasource.cpp (modified) (7 diffs)
- trunk/gdal/ogr/ogrsf_frmts/kml/ogrkmldriver.cpp (modified) (3 diffs)
- trunk/gdal/ogr/ogrsf_frmts/kml/ogrkmllayer.cpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/gdal/ogr/ogrsf_frmts/kml/GNUmakefile
r9790 r12091 3 3 include ../../../GDALmake.opt 4 4 5 CORE_OBJ = kmlfeatureclass.o kmlfeature.o ogr2kmlgeometry.o5 CORE_OBJ = ogr2kmlgeometry.o 6 6 7 OGR_OBJ = ogrkmldriver.o ogrkmldatasource.o ogrkmllayer.o 7 OGR_OBJ = ogrkmldriver.o ogrkmldatasource.o ogrkmllayer.o kml.o kmlvector.o kmlnode.o 8 8 9 9 OBJ = $(CORE_OBJ) $(OGR_OBJ) 10 10 11 CPPFLAGS := -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS) 11 CPPFLAGS := -I.. -I../.. $(GDAL_INCLUDE) $(CPPFLAGS) -Wall -ansi 12 12 #CFLAGS := $(filter-out -Wall,$(CFLAGS)) 13 13 … … 18 18 19 19 20 trunk/gdal/ogr/ogrsf_frmts/kml/makefile.vc
r9802 r12091 1 1 2 LL_OBJ = kml featureclass.obj kmlfeature.obj ogr2kmlgeometry.obj2 LL_OBJ = kml.obj kmlvector.obj ogr2kmlgeometry.obj kmlnode.obj 3 3 OGR_OBJ = ogrkmldriver.obj ogrkmldatasource.obj ogrkmllayer.obj 4 4 … … 9 9 !INCLUDE $(GDAL_ROOT)\nmake.opt 10 10 11 EXTRAFLAGS = -I.. -I..\.. 11 !IFDEF EXPAT_DIR 12 EXTRAFLAGS = -I.. -I..\.. $(EXPAT_INCLUDE) -DHAVE_EXPAT=1 13 !ELSE 14 EXTRAFLAGS = -I.. -I..\.. -DHAVE_EXPAT=0 15 !ENDIF 16 12 17 13 18 default: $(OBJ) trunk/gdal/ogr/ogrsf_frmts/kml/ogr2kmlgeometry.cpp
r11885 r12091 236 236 "<Polygon>" ); 237 237 238 OGRLinearRing *poExteriorRing = poPolygon->getExteriorRing(); 239 if( poExteriorRing != NULL ) 240 { 241 /* Test if we need to reverse the winding order. The KML specification 242 * defines the front of a face as a LinearRing with anti-clockwise 243 * winding order. Full 3D implementations of KML, such as Google Earth, 244 * light the front of the face, not the rear. 245 * For the present case it's safe to assume that all faces exported 246 * from OGR should have anti-clockwise winding orders. 247 */ 248 if ( poExteriorRing->isClockwise() ) 249 { 250 poExteriorRing->reverseWindingOrder(); 251 } 252 238 if( poPolygon->getExteriorRing() != NULL ) 239 { 253 240 AppendString( ppszText, pnLength, pnMaxLength, 254 241 "<outerBoundaryIs>" ); 255 242 256 if( !OGR2KMLGeometryAppend( po ExteriorRing,243 if( !OGR2KMLGeometryAppend( poPolygon->getExteriorRing(), 257 244 ppszText, pnLength, pnMaxLength ) ) 258 {259 245 return FALSE; 260 } 261 246 262 247 AppendString( ppszText, pnLength, pnMaxLength, 263 248 "</outerBoundaryIs>" ); … … 267 252 { 268 253 OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing); 269 270 /* Perform the winding test again. */271 if( poRing->isClockwise() )272 {273 poRing->reverseWindingOrder();274 }275 254 276 255 AppendString( ppszText, pnLength, pnMaxLength, trunk/gdal/ogr/ogrsf_frmts/kml/ogr_kml.h
r10645 r12091 5 5 * Purpose: Declarations for OGR wrapper classes for KML, and OGR->KML 6 6 * translation of geometry. 7 * Author: Christopher Condit, condit@sdsc.edu 7 * Author: Christopher Condit, condit@sdsc.edu; 8 * Jens Oberender, j.obi@troja.net 8 9 * 9 10 ****************************************************************************** 10 11 * Copyright (c) 2006, Christopher Condit 12 * 2007, Jens Oberender 11 13 * 12 14 * Permission is hereby granted, free of charge, to any person obtaining a … … 32 34 33 35 #include "ogrsf_frmts.h" 34 #include "kml reader.h"36 #include "kmlvector.h" 35 37 36 38 class OGRKMLDataSource; … … 42 44 class OGRKMLLayer : public OGRLayer 43 45 { 46 private: 44 47 OGRSpatialReference *poSRS; 45 48 OGRFeatureDefn *poFeatureDefn; 46 49 47 int iNextKMLId; 50 unsigned short iNextKMLId; 51 unsigned short nNextFID; 48 52 int nTotalKMLCount; 49 53 … … 52 56 OGRKMLDataSource *poDS; 53 57 54 KMLFeatureClass *poFClass;58 unsigned short nLayerNumber; 55 59 56 60 public: … … 70 74 71 75 OGRErr CreateFeature( OGRFeature *poFeature ); 72 76 73 77 OGRFeatureDefn * GetLayerDefn() { return poFeatureDefn; } 74 78 … … 77 81 78 82 virtual OGRSpatialReference *GetSpatialRef(); 83 84 void SetLayerNumber(unsigned short); 79 85 80 86 int TestCapability( const char * ); … … 87 93 class OGRKMLDataSource : public OGRDataSource 88 94 { 89 OGRKMLLayer **papoLayers;95 OGRKMLLayer **papoLayers; 90 96 int nLayers; 91 97 92 98 char *pszName; 93 99 94 OGRKMLLayer *TranslateKMLSchema( KMLFeatureClass * );95 96 100 //The name of the field to use for 97 101 char *pszNameField; … … 106 110 int nSchemaInsertLocation; 107 111 108 // input related parameters. 109 //IKMLReader *poReader; 112 KML *poKMLFile; 110 113 111 114 void InsertHeader(); … … 132 135 133 136 FILE *GetOutputFP() { return fpOutput; } 134 //IKMLReader *GetReader() { return poReader; }135 137 136 138 void GrowExtents( OGREnvelope *psGeomBounds ); 139 140 KML* GetKMLFile() { return poKMLFile; }; 137 141 138 142 }; … … 157 161 158 162 #endif /* OGR_KML_H_INCLUDED */ 163 trunk/gdal/ogr/ogrsf_frmts/kml/ogrkmldatasource.cpp
r10645 r12091 4 4 * Project: KML Driver 5 5 * Purpose: Implementation of OGRKMLDataSource class. 6 * Author: Christopher Condit, condit@sdsc.edu 6 * Author: Christopher Condit, condit@sdsc.edu; 7 * Jens Oberender, j.obi@troja.net 7 8 * 8 9 ****************************************************************************** 9 10 * Copyright (c) 2006, Christopher Condit 11 * 2007, Jens Oberender 10 12 * 11 13 * Permission is hereby granted, free of charge, to any person obtaining a … … 31 33 #include "cpl_string.h" 32 34 #include "cpl_error.h" 33 34 /************************************************************************/ 35 /* OGRKMLDataSource() */ 35 #include "cpl_minixml.h" 36 37 /************************************************************************/ 38 /* OGRKMLDataSource() */ 36 39 /************************************************************************/ 37 40 OGRKMLDataSource::OGRKMLDataSource() … … 48 51 49 52 /************************************************************************/ 50 /* ~OGRKMLDataSource() */53 /* ~OGRKMLDataSource() */ 51 54 /************************************************************************/ 52 55 OGRKMLDataSource::~OGRKMLDataSource() … … 72 75 CPLFree( papoLayers ); 73 76 77 if(this->poKMLFile != NULL) 78 delete this->poKMLFile; 74 79 } 75 80 … … 79 84 int OGRKMLDataSource::Open( const char * pszNewName, int bTestOpen ) 80 85 { 81 FILE *fp; 82 char szHeader[1000]; 83 86 int nCount; 87 OGRKMLLayer *poLayer; 88 OGRwkbGeometryType poGeotype; 89 84 90 CPLAssert( NULL != pszNewName ); 85 91 86 92 /* -------------------------------------------------------------------- */ 87 /* Open the source file. */ 88 /* -------------------------------------------------------------------- */ 89 fp = VSIFOpen( pszNewName, "r" ); 90 if( fp == NULL ) 91 { 92 if( !bTestOpen ) 93 CPLError( CE_Failure, CPLE_OpenFailed, 94 "Failed to open KML file `%s'.", 95 pszNewName ); 96 97 return FALSE; 98 } 99 100 /* -------------------------------------------------------------------- */ 101 /* If we aren't sure it is KML, load a header chunk and check */ 102 /* for signs it is KML */ 103 /* -------------------------------------------------------------------- */ 104 if( bTestOpen ) 105 { 106 VSIFRead( szHeader, 1, sizeof(szHeader), fp ); 107 szHeader[sizeof(szHeader)-1] = '\0'; 108 109 if( szHeader[0] != '<' 110 || strstr(szHeader, "http://earth.google.com/kml/2.0") == NULL ) 111 { 112 VSIFClose( fp ); 113 return FALSE; 93 /* Create a KML object and open the source file. */ 94 /* -------------------------------------------------------------------- */ 95 this->poKMLFile = new KMLvector(); 96 if( !this->poKMLFile->open( pszNewName )) { 97 delete this->poKMLFile; 98 this->poKMLFile = NULL; 99 return FALSE; 100 } 101 this->pszName = CPLStrdup( pszNewName ); 102 103 /* -------------------------------------------------------------------- */ 104 /* If we aren't sure it is KML, validate it by start parsing */ 105 /* -------------------------------------------------------------------- */ 106 if( bTestOpen && !poKMLFile->isValid()) 107 { 108 delete this->poKMLFile; 109 this->poKMLFile = NULL; 110 return FALSE; 111 } 112 113 /* -------------------------------------------------------------------- */ 114 /* Prescan the KML file so we can later work with the structure */ 115 /* -------------------------------------------------------------------- */ 116 this->poKMLFile->parse(); 117 118 /* -------------------------------------------------------------------- */ 119 /* Classify the nodes */ 120 /* -------------------------------------------------------------------- */ 121 this->poKMLFile->classifyNodes(); 122 123 /* -------------------------------------------------------------------- */ 124 /* Eliminate the empty containers */ 125 /* -------------------------------------------------------------------- */ 126 this->poKMLFile->eliminateEmpty(); 127 128 /* -------------------------------------------------------------------- */ 129 /* Find layers to use in the KML structure */ 130 /* -------------------------------------------------------------------- */ 131 this->poKMLFile->findLayers(NULL); 132 133 /* -------------------------------------------------------------------- */ 134 /* Print the structure */ 135 /* -------------------------------------------------------------------- */ 136 this->poKMLFile->print(3); 137 138 nLayers = this->poKMLFile->numLayers(); 139 140 /* -------------------------------------------------------------------- */ 141 /* Allocate memory for the Layers */ 142 /* -------------------------------------------------------------------- */ 143 papoLayers = (OGRKMLLayer **) 144 CPLMalloc( sizeof(OGRKMLLayer *) * nLayers ); 145 146 OGRSpatialReference *poSRS = new OGRSpatialReference("GEOGCS[\"WGS 84\", " 147 " DATUM[\"WGS_1984\"," 148 " SPHEROID[\"WGS 84\",6378137,298.257223563," 149 " AUTHORITY[\"EPSG\",\"7030\"]]," 150 " AUTHORITY[\"EPSG\",\"6326\"]]," 151 " PRIMEM[\"Greenwich\",0," 152 " AUTHORITY[\"EPSG\",\"8901\"]]," 153 " UNIT[\"degree\",0.01745329251994328," 154 " AUTHORITY[\"EPSG\",\"9122\"]]," 155 " AUTHORITY[\"EPSG\",\"4326\"]]"); 156 157 /* -------------------------------------------------------------------- */ 158 /* Create the Layers and fill them */ 159 /* -------------------------------------------------------------------- */ 160 for(nCount = 0; nCount < nLayers; nCount++) { 161 CPLDebug("KML", "Loading Layer #%d", nCount); 162 if(!this->poKMLFile->selectLayer(nCount)) { 163 CPLError(CE_Failure, CPLE_AppDefined, 164 "There are no layers or a layer can not be found!"); 165 break; 114 166 } 115 } 116 117 VSIFClose( fp ); 118 119 CPLError( CE_Failure, CPLE_AppDefined, 120 "Reading KML files is not currently supported\n"); 121 167 168 if(this->poKMLFile->getCurrentType() == Point) 169 poGeotype = wkbPoint; 170 else if(this->poKMLFile->getCurrentType() == LineString) 171 poGeotype = wkbLineString; 172 else if(this->poKMLFile->getCurrentType() == Polygon) 173 poGeotype = wkbPolygon; 174 else 175 poGeotype = wkbUnknown; 176 177 /* -------------------------------------------------------------------- */ 178 /* Create the layer object. */ 179 /* -------------------------------------------------------------------- */ 180 std::string sName = this->poKMLFile->getCurrentName(); 181 if(sName.compare("") == 0) { 182 char *pszName = new char[10]; 183 snprintf(pszName, 10, "Layer #%d", nCount); 184 sName = pszName; 185 if(pszName != NULL) 186 delete pszName; 187 } 188 189 poLayer = new OGRKMLLayer( sName.c_str(), poSRS, FALSE, poGeotype, this ); 190 191 poLayer->SetLayerNumber(nCount); 192 193 /* -------------------------------------------------------------------- */ 194 /* Add layer to data source layer list. */ 195 /* -------------------------------------------------------------------- */ 196 papoLayers[nCount] = poLayer; 197 } 198 199 poSRS->Release(); 200 122 201 return TRUE; 123 }124 125 /************************************************************************/126 /* TranslateKMLSchema() */127 /************************************************************************/128 OGRKMLLayer *OGRKMLDataSource::TranslateKMLSchema( KMLFeatureClass *poClass )129 {130 CPLAssert( NULL != poClass );131 132 OGRKMLLayer *poLayer;133 poLayer = new OGRKMLLayer( poClass->GetName(), NULL, FALSE,134 wkbUnknown, this );135 136 return poLayer;137 202 } 138 203 … … 211 276 212 277 /* -------------------------------------------------------------------- */ 213 /* Close the previous layer (if there is one open) */278 /* Close the previous layer (if there is one open) */ 214 279 /* -------------------------------------------------------------------- */ 215 280 if (GetLayerCount() > 0) … … 266 331 OGRLayer *OGRKMLDataSource::GetLayer( int iLayer ) 267 332 { 333 CPLDebug("KML", "Get Layer #%d", iLayer); 268 334 if( iLayer < 0 || iLayer >= nLayers ) 269 335 return NULL; trunk/gdal/ogr/ogrsf_frmts/kml/ogrkmldriver.cpp
r10645 r12091 4 4 * Project: KML Driver 5 5 * Purpose: Implementation of OGRKMLDriver class. 6 * Author: Christopher Condit, condit@sdsc.edu 6 * Author: Christopher Condit, condit@sdsc.edu; 7 * Jens Oberender, j.obi@troja.net 7 8 * 8 9 ****************************************************************************** 9 10 * Copyright (c) 2006, Christopher Condit 11 * 2007, Jens Oberender 10 12 * 11 13 * Permission is hereby granted, free of charge, to any person obtaining a … … 61 63 poDS = new OGRKMLDataSource(); 62 64 63 if( !poDS->Open( pszFilename, TRUE ) 64 || poDS->GetLayerCount() == 0 ) 65 if( !poDS->Open( pszFilename, TRUE ) ) 65 66 { 67 delete poDS; 68 return NULL; 69 } 70 71 if( poDS->GetLayerCount() == 0 ) 72 { 73 CPLError( CE_Failure, CPLE_OpenFailed, 74 "No layers in KML file: `%s'.", 75 pszFilename ); 76 66 77 delete poDS; 67 78 return NULL; … … 110 121 } 111 122 123 trunk/gdal/ogr/ogrsf_frmts/kml/ogrkmllayer.cpp
r10645 r12091 5 5 * Purpose: Implementation of OGRKMLLayer class. 6 6 * Author: Christopher Condit, condit@sdsc.edu 7 * Jens Oberender, j.obi@troja.net 7 8 * 8 9 ****************************************************************************** … … 33 34 #include "cpl_string.h" 34 35 35 / / Function utility to dump OGRGeoemtry to KML text36 /* Function utility to dump OGRGeoemtry to KML text. */ 36 37 char *OGR_G_ExportToKML( OGRGeometryH hGeometry ); 37 38 … … 45 46 { 46 47 if( poSRSIn == NULL ) 47 poSRS = NULL;48 this->poSRS = NULL; 48 49 else 49 poSRS = poSRSIn->Clone(); 50 51 iNextKMLId = 0; 52 nTotalKMLCount = -1; 53 54 poDS = poDSIn; 55 56 poFeatureDefn = new OGRFeatureDefn( pszName ); 57 poFeatureDefn->Reference(); 58 poFeatureDefn->SetGeomType( eReqType ); 59 60 bWriter = bWriterIn; 61 62 poFClass = NULL; 63 } 64 65 /************************************************************************/ 66 /* ~OGRKMLLayer() */ 50 this->poSRS = poSRSIn->Clone(); 51 52 this->iNextKMLId = 0; 53 this->nTotalKMLCount = -1; 54 55 this->poDS = poDSIn; 56 57 this->poFeatureDefn = new OGRFeatureDefn( pszName ); 58 this->poFeatureDefn->Reference(); 59 this->poFeatureDefn->SetGeomType( eReqType ); 60 61 OGRFieldDefn *oFieldTemplate = new OGRFieldDefn( "Name", OFTString ); 62 this->poFeatureDefn->AddFieldDefn( oFieldTemplate ); 63 delete oFieldTemplate; 64 oFieldTemplate = new OGRFieldDefn( "Description", OFTString ); 65 this->poFeatureDefn->AddFieldDefn( oFieldTemplate ); 66 delete oFieldTemplate; 67 68 this->bWriter = bWriterIn; 69 70 } 71 72 /************************************************************************/ 73 /* ~OGRKMLLayer() */ 67 74 /************************************************************************/ 68 75 OGRKMLLayer::~OGRKMLLayer() … … 88 95 OGRFeature *OGRKMLLayer::GetNextFeature() 89 96 { 90 CPLError( CE_Failure, CPLE_AppDefined, 91 "OGRKMLLayer::GetExtent: KML driver is write-only!\n"); 92 93 return NULL; 97 CPLDebug("KML", "GetNextFeature(#%d)", this->iNextKMLId); 98 Feature *poFeatureKML; 99 unsigned short nCount, nCount2; 100 KML *poKMLFile = poDS->GetKMLFile(); 101 poKMLFile->selectLayer(this->nLayerNumber); 102 103 poFeatureKML = poKMLFile->getFeature(this->iNextKMLId++); 104 105 if(poFeatureKML == NULL) 106 return NULL; 107 if(this->poFeatureDefn == NULL) 108 CPLDebug("KML", "Ohoh"); 109 110 OGRFeature *poFeature = new OGRFeature( this->poFeatureDefn ); 111 112 // Handle a Point 113 if(poFeatureKML->eType == Point) 114 { 115 poFeature->SetGeometryDirectly( 116 new OGRPoint( poFeatureKML->pvpsCoordinates->at(0)->dfLongitude, poFeatureKML->pvpsCoordinates->at(0)->dfLatitude, poFeatureKML->pvpsCoordinates->at(0)->dfAltitude) 117 ); 118 } 119 // Handle a LineString 120 else if(poFeatureKML->eType == LineString) 121 { 122 OGRLineString *poLS = new OGRLineString(); 123 for(nCount = 0; nCount < poFeatureKML->pvpsCoordinates->size(); nCount++) 124 { 125 poLS->addPoint(poFeatureKML->pvpsCoordinates->at(nCount)->dfLongitude, poFeatureKML->pvpsCoordinates->at(nCount)->dfLatitude, poFeatureKML->pvpsCoordinates->at(nCount)->dfAltitude); 126 } 127 poFeature->SetGeometryDirectly(poLS); 128 } 129 // Handle a Polygon 130 else if(poFeatureKML->eType == Polygon) 131 { 132 OGRPolygon *poPG = new OGRPolygon(); 133 OGRLinearRing *poLR = new OGRLinearRing(); 134 for(nCount = 0; nCount < poFeatureKML->pvpsCoordinates->size(); nCount++) 135 { 136 poLR->addPoint(poFeatureKML->pvpsCoordinates->at(nCount)->dfLongitude, poFeatureKML->pvpsCoordinates->at(nCount)->dfLatitude, poFeatureKML->pvpsCoordinates->at(nCount)->dfAltitude); 137 } 138 poPG->addRingDirectly(poLR); 139 for(nCount = 0; nCount < poFeatureKML->pvpsCoordinatesExtra->size(); nCount++) 140 { 141 poLR = new OGRLinearRing(); 142 for(nCount2 = 0; nCount2 < poFeatureKML->pvpsCoordinatesExtra->at(nCount)->size(); nCount2++) 143 { 144 poLR->addPoint(poFeatureKML->pvpsCoordinatesExtra->at(nCount)->at(nCount2)->dfLongitude, 145 poFeatureKML->pvpsCoordinatesExtra->at(nCount)->at(nCount2)->dfLatitude, 146 poFeatureKML->pvpsCoordinatesExtra->at(nCount)->at(nCount2)->dfAltitude); 147 } 148 poPG->addRingDirectly(poLR); 149 } 150 poFeature->SetGeometryDirectly(poPG); 151 } 152 153 // Add fields 154 poFeature->SetField( poFeatureDefn->GetFieldIndex("Name"), poFeatureKML->sName.c_str() ); 155 poFeature->SetField( poFeatureDefn->GetFieldIndex("Description"), poFeatureKML->sDescription.c_str() ); 156 poFeature->SetFID( this->nNextFID++ ); 157 158 // Clean up 159 for(nCount = 0; nCount < poFeatureKML->pvpsCoordinates->size(); nCount++) 160 { 161 delete poFeatureKML->pvpsCoordinates->at(nCount); 162 } 163 164 if(poFeatureKML->pvpsCoordinatesExtra != NULL) 165 { 166 for(nCount = 0; nCount < poFeatureKML->pvpsCoordinatesExtra->size(); nCount++) 167 { 168 for(nCount2 = 0; nCount2 < poFeatureKML->pvpsCoordinatesExtra->at(nCount)->size(); nCount2++) 169 delete poFeatureKML->pvpsCoordinatesExtra->at(nCount)->at(nCount2); 170 delete poFeatureKML->pvpsCoordinatesExtra->at(nCount); 171 } 172 delete poFeatureKML->pvpsCoordinatesExtra; 173 } 174 175 delete poFeatureKML->pvpsCoordinates; 176 delete poFeatureKML; 177 178 // Return the feature 179 return poFeature; 94 180 } 95 181 … … 99 185 int OGRKMLLayer::GetFeatureCount( int bForce ) 100 186 { 101 if( poFClass == NULL ) 102 return 0; 103 104 if( m_poFilterGeom != NULL || m_poAttrQuery != NULL ) 105 return OGRLayer::GetFeatureCount( bForce ); 106 else 107 return poFClass->GetFeatureCount(); 187 KML *poKMLFile = poDS->GetKMLFile(); 188 poKMLFile->selectLayer(this->nLayerNumber); 189 190 return poKMLFile->getNumFeatures(); 108 191 } 109 192 … … 115 198 CPLAssert( NULL != psExtent ); 116 199 117 CPLError( CE_Failure, CPLE_AppDefined, 118 "OGRKMLLayer::GetExtent: KML driver is write-only!\n"); 119 120 return OGRERR_NONE; 200 double dfXMin, dfXMax, dfYMin, dfYMax; 201 202 KML *poKMLFile = poDS->GetKMLFile(); 203 poKMLFile->selectLayer(this->nLayerNumber); 204 205 if(poKMLFile->getExtents( &dfXMin, &dfXMax, &dfYMin, &dfYMax )) 206 { 207 psExtent->MinX = dfXMin; 208 psExtent->MaxX = dfXMax; 209 psExtent->MinY = dfYMin; 210 psExtent->MaxY = dfYMax; 211 212 return OGRERR_NONE; 213 } 214 else 215 return OGRERR_FAILURE; 121 216 } 122 217 … … 126 221 OGRErr OGRKMLLayer::CreateFeature( OGRFeature *poFeature ) 127 222 { 128 FILE *fp = poDS->GetOutputFP();223 FILE *fp = poDS->GetOutputFP(); 129 224 130 225 if( !bWriter ) … … 144 239 OGRFieldDefn *poField = poFeatureDefn->GetFieldDefn( iField ); 145 240 146 if ( poFeature->IsFieldSet( iField ) &&147 !strcmp(poField->GetNameRef(), poDS->GetNameField()))241 if( poFeature->IsFieldSet( iField ) 242 && !strcmp(poField->GetNameRef(), poDS->GetNameField()) ) 148 243 { 149 244 const char *pszRaw = poFeature->GetFieldAsString( iField ); … … 160 255 161 256 VSIFPrintf( fp, " <description><