1180
1210
if (strstr(pszName, "href"))
1182
VSIFPrintf(fp, " <link href=\"%s\">", poFeature->GetFieldAsString( i ));
1212
AddIdent(fp, nIdentLevel);
1213
VSIFPrintfL(fp, "<link href=\"%s\">", poFeature->GetFieldAsString( i ));
1183
1214
if( poFeature->IsFieldSet( i + 1 ) )
1184
VSIFPrintf(fp, "<text>%s</text>", poFeature->GetFieldAsString( i + 1 ));
1215
VSIFPrintfL(fp, "<text>%s</text>", poFeature->GetFieldAsString( i + 1 ));
1185
1216
if( poFeature->IsFieldSet( i + 2 ) )
1186
VSIFPrintf(fp, "<type>%s</type>", poFeature->GetFieldAsString( i + 2 ));
1187
VSIFPrintf(fp, "</link>\n");
1217
VSIFPrintfL(fp, "<type>%s</type>", poFeature->GetFieldAsString( i + 2 ));
1218
poDS->PrintLine("</link>");
1221
else if (poFieldDefn->GetType() == OFTReal)
1224
OGRFormatDouble(szValue, sizeof(szValue), poFeature->GetFieldAsDouble(i), '.');
1225
AddIdent(fp, nIdentLevel);
1226
poDS->PrintLine("<%s>%s</%s>", pszName, szValue, pszName);
1192
1230
char* pszValue =
1193
1231
OGRGetXML_UTF8_EscapedString(poFeature->GetFieldAsString( i ));
1194
VSIFPrintf(fp, " <%s>%s</%s>\n",
1195
pszName, pszValue, pszName);
1232
AddIdent(fp, nIdentLevel);
1233
poDS->PrintLine("<%s>%s</%s>", pszName, pszValue, pszName);
1196
1234
CPLFree(pszValue);
1212
1251
char* compatibleName =
1213
1252
OGRGPX_GetXMLCompatibleTagName(pszExtensionsNS, poFieldDefn->GetNameRef());
1214
const char *pszRaw = poFeature->GetFieldAsString( i );
1216
/* Try to detect XML content */
1217
if (pszRaw[0] == '<' && pszRaw[strlen(pszRaw) - 1] == '>')
1254
if (poFieldDefn->GetType() == OFTReal)
1219
if (OGRGPX_WriteXMLExtension(fp, compatibleName, pszRaw))
1257
OGRFormatDouble(szValue, sizeof(szValue), poFeature->GetFieldAsDouble(i), '.');
1258
AddIdent(fp, nIdentLevel + 1);
1259
poDS->PrintLine("<%s:%s>%s</%s:%s>",
1223
/* Try to detect XML escaped content */
1224
else if (strncmp(pszRaw, "<", 4) == 0 &&
1225
strncmp(pszRaw + strlen(pszRaw) - 4, ">", 4) == 0)
1227
char* pszUnescapedContent = CPLUnescapeString( pszRaw, NULL, CPLES_XML );
1229
if (OGRGPX_WriteXMLExtension(fp, compatibleName, pszUnescapedContent))
1268
const char *pszRaw = poFeature->GetFieldAsString( i );
1270
/* Try to detect XML content */
1271
if (pszRaw[0] == '<' && pszRaw[strlen(pszRaw) - 1] == '>')
1273
if (OGRGPX_WriteXMLExtension( compatibleName, pszRaw))
1277
/* Try to detect XML escaped content */
1278
else if (strncmp(pszRaw, "<", 4) == 0 &&
1279
strncmp(pszRaw + strlen(pszRaw) - 4, ">", 4) == 0)
1281
char* pszUnescapedContent = CPLUnescapeString( pszRaw, NULL, CPLES_XML );
1283
if (OGRGPX_WriteXMLExtension(compatibleName, pszUnescapedContent))
1285
CPLFree(pszUnescapedContent);
1231
1289
CPLFree(pszUnescapedContent);
1235
CPLFree(pszUnescapedContent);
1238
/* Remove leading spaces for a numeric field */
1239
if (poFieldDefn->GetType() == OFTInteger || poFieldDefn->GetType() == OFTReal)
1241
while( *pszRaw == ' ' )
1245
char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw );
1246
VSIFPrintf(fp, " <%s:%s>%s</%s:%s>\n",
1292
/* Remove leading spaces for a numeric field */
1293
if (poFieldDefn->GetType() == OFTInteger || poFieldDefn->GetType() == OFTReal)
1295
while( *pszRaw == ' ' )
1299
char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw );
1300
AddIdent(fp, nIdentLevel + 1);
1301
poDS->PrintLine("<%s:%s>%s</%s:%s>",
1307
CPLFree(pszEscaped);
1252
1309
CPLFree(compatibleName);
1253
CPLFree(pszEscaped);
1256
VSIFPrintf(fp, " </extensions>\n");
1312
AddIdent(fp, nIdentLevel);
1313
poDS->PrintLine("</extensions>");
1330
1391
poDS->SetLastGPXGeomTypeWritten(gpxGeomType);
1332
if ( poGeom == NULL )
1334
CPLError( CE_Failure, CPLE_AppDefined,
1335
"Features without geometry not supported by GPX writer in waypoints layer." );
1336
return OGRERR_FAILURE;
1339
switch( poGeom->getGeometryType() )
1344
OGRPoint* point = (OGRPoint*)poGeom;
1345
double lat = point->getY();
1346
double lon = point->getX();
1347
CheckAndFixCoordinatesValidity(&lat, &lon);
1348
poDS->AddCoord(lon, lat);
1349
VSIFPrintf(fp, "<wpt lat=\"%.15f\" lon=\"%.15f\">\n", lat, lon);
1350
WriteFeatureAttributes(poFeature);
1351
VSIFPrintf(fp, "</wpt>\n");
1357
CPLError( CE_Failure, CPLE_NotSupported,
1358
"Geometry type of `%s' not supported fort 'wpt' element.\n",
1359
OGRGeometryTypeToName(poGeom->getGeometryType()) );
1360
return OGRERR_FAILURE;
1393
if ( poGeom == NULL || wkbFlatten(poGeom->getGeometryType()) != wkbPoint )
1395
CPLError( CE_Failure, CPLE_AppDefined,
1396
"Features without geometry or with non-ponctual geometries not supported by GPX writer in waypoints layer." );
1397
return OGRERR_FAILURE;
1400
if ( poGeom->getCoordinateDimension() == 0 )
1402
CPLError( CE_Failure, CPLE_AppDefined,
1403
"POINT EMPTY geometries not supported by GPX writer." );
1404
return OGRERR_FAILURE;
1407
OGRPoint* point = (OGRPoint*)poGeom;
1408
double lat = point->getY();
1409
double lon = point->getX();
1410
CheckAndFixCoordinatesValidity(&lat, &lon);
1411
poDS->AddCoord(lon, lat);
1412
OGRFormatDouble(szLat, sizeof(szLat), lat, '.');
1413
OGRFormatDouble(szLon, sizeof(szLon), lon, '.');
1414
poDS->PrintLine("<wpt lat=\"%s\" lon=\"%s\">", szLat, szLon);
1415
WriteFeatureAttributes(poFeature);
1416
poDS->PrintLine("</wpt>");
1364
1418
else if (gpxGeomType == GPX_ROUTE)
1366
if (poDS->GetLastGPXGeomTypeWritten() == GPX_TRACK)
1420
if (poDS->GetLastGPXGeomTypeWritten() == GPX_TRACK ||
1421
poDS->GetLastGPXGeomTypeWritten() == GPX_TRACK_POINT)
1368
1423
CPLError( CE_Failure, CPLE_NotSupported,
1369
1424
"Cannot write a 'rte' element after a 'trk' element.\n");
1370
1425
return OGRERR_FAILURE;
1428
if (poDS->GetLastGPXGeomTypeWritten() == GPX_ROUTE_POINT && poDS->nLastRteId != -1)
1430
poDS->PrintLine("</rte>");
1431
poDS->nLastRteId = -1;
1373
1434
poDS->SetLastGPXGeomTypeWritten(gpxGeomType);
1375
1436
OGRLineString* line = NULL;
1377
1438
if ( poGeom == NULL )
1379
VSIFPrintf(fp, "<rte>\n");
1440
poDS->PrintLine("<rte>");
1380
1441
WriteFeatureAttributes(poFeature);
1381
VSIFPrintf(fp, "</rte>\n");
1442
poDS->PrintLine("</rte>");
1382
1443
return OGRERR_NONE;
1431
1492
double lon = line->getX(i);
1432
1493
CheckAndFixCoordinatesValidity(&lat, &lon);
1433
1494
poDS->AddCoord(lon, lat);
1434
VSIFPrintf(fp, " <rtept lat=\"%.15f\" lon=\"%.15f\">\n", lat, lon);
1495
OGRFormatDouble(szLat, sizeof(szLat), lat, '.');
1496
OGRFormatDouble(szLon, sizeof(szLon), lon, '.');
1497
poDS->PrintLine(" <rtept lat=\"%s\" lon=\"%s\">", szLat, szLon);
1435
1498
if (poGeom->getGeometryType() == wkbLineString25D ||
1436
1499
poGeom->getGeometryType() == wkbMultiLineString25D)
1438
VSIFPrintf(fp, " <ele>%f</ele>\n", line->getZ(i));
1501
OGRFormatDouble(szAlt, sizeof(szAlt), line->getZ(i), '.');
1502
poDS->PrintLine(" <ele>%s</ele>", szAlt);
1440
VSIFPrintf(fp, " </rtept>\n");
1504
poDS->PrintLine(" </rtept>");
1442
VSIFPrintf(fp, "</rte>\n");
1506
poDS->PrintLine("</rte>");
1508
else if (gpxGeomType == GPX_TRACK)
1510
if (poDS->GetLastGPXGeomTypeWritten() == GPX_ROUTE_POINT && poDS->nLastRteId != -1)
1512
poDS->PrintLine("</rte>");
1513
poDS->nLastRteId = -1;
1515
if (poDS->GetLastGPXGeomTypeWritten() == GPX_TRACK_POINT && poDS->nLastTrkId != -1)
1517
poDS->PrintLine(" </trkseg>");
1518
poDS->PrintLine("</trk>");
1519
poDS->nLastTrkId = -1;
1520
poDS->nLastTrkSegId = -1;
1446
1523
poDS->SetLastGPXGeomTypeWritten(gpxGeomType);
1448
1525
if (poGeom == NULL)
1450
VSIFPrintf(fp, "<trk>\n");
1527
poDS->PrintLine("<trk>");
1451
1528
WriteFeatureAttributes(poFeature);
1452
VSIFPrintf(fp, "</trk>\n");
1529
poDS->PrintLine("</trk>");
1453
1530
return OGRERR_NONE;
1461
1538
OGRLineString* line = (OGRLineString*)poGeom;
1462
1539
int n = line->getNumPoints();
1464
VSIFPrintf(fp, "<trk>\n");
1541
poDS->PrintLine("<trk>");
1465
1542
WriteFeatureAttributes(poFeature);
1466
VSIFPrintf(fp, " <trkseg>\n");
1543
poDS->PrintLine(" <trkseg>");
1467
1544
for(i=0;i<n;i++)
1469
1546
double lat = line->getY(i);
1470
1547
double lon = line->getX(i);
1471
1548
CheckAndFixCoordinatesValidity(&lat, &lon);
1472
1549
poDS->AddCoord(lon, lat);
1473
VSIFPrintf(fp, " <trkpt lat=\"%.15f\" lon=\"%.15f\">\n", lat, lon);
1550
OGRFormatDouble(szLat, sizeof(szLat), lat, '.');
1551
OGRFormatDouble(szLon, sizeof(szLon), lon, '.');
1552
poDS->PrintLine(" <trkpt lat=\"%s\" lon=\"%s\">", szLat, szLon);
1474
1553
if (line->getGeometryType() == wkbLineString25D)
1476
VSIFPrintf(fp, " <ele>%f</ele>\n", line->getZ(i));
1555
OGRFormatDouble(szAlt, sizeof(szAlt), line->getZ(i), '.');
1556
poDS->PrintLine(" <ele>%s</ele>", szAlt);
1478
VSIFPrintf(fp, " </trkpt>\n");
1558
poDS->PrintLine(" </trkpt>");
1480
VSIFPrintf(fp, " </trkseg>\n");
1481
VSIFPrintf(fp, "</trk>\n");
1560
poDS->PrintLine(" </trkseg>");
1561
poDS->PrintLine("</trk>");
1494
1574
OGRLineString* line = (OGRLineString*) ( ((OGRGeometryCollection*)poGeom)->getGeometryRef(j) );
1495
1575
int n = (line) ? line->getNumPoints() : 0;
1497
VSIFPrintf(fp, " <trkseg>\n");
1577
poDS->PrintLine(" <trkseg>");
1498
1578
for(i=0;i<n;i++)
1500
1580
double lat = line->getY(i);
1501
1581
double lon = line->getX(i);
1502
1582
CheckAndFixCoordinatesValidity(&lat, &lon);
1503
1583
poDS->AddCoord(lon, lat);
1504
VSIFPrintf(fp, " <trkpt lat=\"%.15f\" lon=\"%.15f\">\n", lat, lon);
1584
OGRFormatDouble(szLat, sizeof(szLat), lat, '.');
1585
OGRFormatDouble(szLon, sizeof(szLon), lon, '.');
1586
poDS->PrintLine(" <trkpt lat=\"%s\" lon=\"%s\">", szLat, szLon);
1505
1587
if (line->getGeometryType() == wkbLineString25D)
1507
VSIFPrintf(fp, " <ele>%f</ele>\n", line->getZ(i));
1589
OGRFormatDouble(szAlt, sizeof(szAlt), line->getZ(i), '.');
1590
poDS->PrintLine(" <ele>%s</ele>", szAlt);
1509
VSIFPrintf(fp, " </trkpt>\n");
1592
poDS->PrintLine(" </trkpt>");
1511
VSIFPrintf(fp, " </trkseg>\n");
1594
poDS->PrintLine(" </trkseg>");
1513
VSIFPrintf(fp, "</trk>\n");
1596
poDS->PrintLine("</trk>");
1609
else if (gpxGeomType == GPX_ROUTE_POINT)
1611
if (poDS->GetLastGPXGeomTypeWritten() == GPX_TRACK ||
1612
poDS->GetLastGPXGeomTypeWritten() == GPX_TRACK_POINT)
1614
CPLError( CE_Failure, CPLE_NotSupported,
1615
"Cannot write a 'rte' element after a 'trk' element.\n");
1616
return OGRERR_FAILURE;
1619
if ( poGeom == NULL || wkbFlatten(poGeom->getGeometryType()) != wkbPoint )
1621
CPLError( CE_Failure, CPLE_AppDefined,
1622
"Features without geometry or with non-ponctual geometries not supported by GPX writer in route_points layer." );
1623
return OGRERR_FAILURE;
1626
if ( poGeom->getCoordinateDimension() == 0 )
1628
CPLError( CE_Failure, CPLE_AppDefined,
1629
"POINT EMPTY geometries not supported by GPX writer." );
1630
return OGRERR_FAILURE;
1633
if ( !poFeature->IsFieldSet(FLD_ROUTE_FID) )
1635
CPLError( CE_Failure, CPLE_AppDefined,
1636
"Field %s must be set.", poFeatureDefn->GetFieldDefn(FLD_ROUTE_FID)->GetNameRef() );
1637
return OGRERR_FAILURE;
1639
if ( poFeature->GetFieldAsInteger(FLD_ROUTE_FID) < 0 )
1641
CPLError( CE_Failure, CPLE_AppDefined,
1642
"Invalid value for field %s.", poFeatureDefn->GetFieldDefn(FLD_ROUTE_FID)->GetNameRef() );
1643
return OGRERR_FAILURE;
1646
poDS->SetLastGPXGeomTypeWritten(gpxGeomType);
1648
if ( poDS->nLastRteId != poFeature->GetFieldAsInteger(FLD_ROUTE_FID))
1650
if (poDS->nLastRteId != -1)
1652
poDS->PrintLine("</rte>");
1654
poDS->PrintLine("<rte>");
1655
if ( poFeature->IsFieldSet(FLD_ROUTE_NAME) )
1658
OGRGetXML_UTF8_EscapedString(poFeature->GetFieldAsString( FLD_ROUTE_NAME ));
1659
poDS->PrintLine(" <%s>%s</%s>",
1660
"name", pszValue, "name");
1665
poDS->nLastRteId = poFeature->GetFieldAsInteger(FLD_ROUTE_FID);
1667
OGRPoint* point = (OGRPoint*)poGeom;
1668
double lat = point->getY();
1669
double lon = point->getX();
1670
CheckAndFixCoordinatesValidity(&lat, &lon);
1671
poDS->AddCoord(lon, lat);
1672
OGRFormatDouble(szLat, sizeof(szLat), lat, '.');
1673
OGRFormatDouble(szLon, sizeof(szLon), lon, '.');
1674
poDS->PrintLine(" <rtept lat=\"%s\" lon=\"%s\">", szLat, szLon);
1675
WriteFeatureAttributes(poFeature, 2);
1676
poDS->PrintLine(" </rtept>");
1681
if (poDS->GetLastGPXGeomTypeWritten() == GPX_ROUTE_POINT && poDS->nLastRteId != -1)
1683
poDS->PrintLine("</rte>");
1684
poDS->nLastRteId = -1;
1687
if ( poGeom == NULL || wkbFlatten(poGeom->getGeometryType()) != wkbPoint )
1689
CPLError( CE_Failure, CPLE_AppDefined,
1690
"Features without geometry or with non-ponctual geometries not supported by GPX writer in track_points layer." );
1691
return OGRERR_FAILURE;
1694
if ( poGeom->getCoordinateDimension() == 0 )
1696
CPLError( CE_Failure, CPLE_AppDefined,
1697
"POINT EMPTY geometries not supported by GPX writer." );
1698
return OGRERR_FAILURE;
1701
if ( !poFeature->IsFieldSet(FLD_TRACK_FID) )
1703
CPLError( CE_Failure, CPLE_AppDefined,
1704
"Field %s must be set.", poFeatureDefn->GetFieldDefn(FLD_TRACK_FID)->GetNameRef() );
1705
return OGRERR_FAILURE;
1707
if ( poFeature->GetFieldAsInteger(FLD_TRACK_FID) < 0 )
1709
CPLError( CE_Failure, CPLE_AppDefined,
1710
"Invalid value for field %s.", poFeatureDefn->GetFieldDefn(FLD_TRACK_FID)->GetNameRef() );
1711
return OGRERR_FAILURE;
1713
if ( !poFeature->IsFieldSet(FLD_TRACK_SEG_ID) )
1715
CPLError( CE_Failure, CPLE_AppDefined,
1716
"Field %s must be set.", poFeatureDefn->GetFieldDefn(FLD_TRACK_SEG_ID)->GetNameRef() );
1717
return OGRERR_FAILURE;
1719
if ( poFeature->GetFieldAsInteger(FLD_TRACK_SEG_ID) < 0 )
1721
CPLError( CE_Failure, CPLE_AppDefined,
1722
"Invalid value for field %s.", poFeatureDefn->GetFieldDefn(FLD_TRACK_SEG_ID)->GetNameRef() );
1723
return OGRERR_FAILURE;
1726
poDS->SetLastGPXGeomTypeWritten(gpxGeomType);
1728
if ( poDS->nLastTrkId != poFeature->GetFieldAsInteger(FLD_TRACK_FID))
1730
if (poDS->nLastTrkId != -1)
1732
poDS->PrintLine(" </trkseg>");
1733
poDS->PrintLine("</trk>");
1735
poDS->PrintLine("<trk>");
1737
if ( poFeature->IsFieldSet(FLD_TRACK_NAME) )
1740
OGRGetXML_UTF8_EscapedString(poFeature->GetFieldAsString( FLD_TRACK_NAME ));
1741
poDS->PrintLine(" <%s>%s</%s>",
1742
"name", pszValue, "name");
1746
poDS->PrintLine(" <trkseg>");
1748
else if (poDS->nLastTrkSegId != poFeature->GetFieldAsInteger(FLD_TRACK_SEG_ID))
1750
poDS->PrintLine(" </trkseg>");
1751
poDS->PrintLine(" <trkseg>");
1754
poDS->nLastTrkId = poFeature->GetFieldAsInteger(FLD_TRACK_FID);
1755
poDS->nLastTrkSegId = poFeature->GetFieldAsInteger(FLD_TRACK_SEG_ID);
1757
OGRPoint* point = (OGRPoint*)poGeom;
1758
double lat = point->getY();
1759
double lon = point->getX();
1760
CheckAndFixCoordinatesValidity(&lat, &lon);
1761
poDS->AddCoord(lon, lat);
1762
OGRFormatDouble(szLat, sizeof(szLat), lat, '.');
1763
OGRFormatDouble(szLon, sizeof(szLon), lon, '.');
1764
poDS->PrintLine(" <trkpt lat=\"%s\" lon=\"%s\">", szLat, szLon);
1765
WriteFeatureAttributes(poFeature, 3);
1766
poDS->PrintLine(" </trkpt>");
1527
1769
return OGRERR_NONE;