kml.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "kml.h"
  2. #define TAG "kml"
  3. bool kml_open_file(Storage* storage, KMLFile* kml, const char* path) {
  4. kml->file = storage_file_alloc(storage);
  5. if(!storage_file_open(kml->file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
  6. // must call close() even if the operation fails
  7. FURI_LOG_E(TAG, "failed to open KML file!");
  8. storage_file_close(kml->file);
  9. storage_file_free(kml->file);
  10. return false;
  11. }
  12. // with the file opened, we need to write the intro KML tags
  13. const char* kml_intro = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  14. "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n"
  15. " <Document>\n"
  16. " <name>Paths</name>\n"
  17. " <Style id=\"yellowLineGreenPoly\">\n"
  18. " <LineStyle>\n"
  19. " <color>7f00ffff</color>\n"
  20. " <width>4</width>\n"
  21. " </LineStyle>\n"
  22. " <PolyStyle>\n"
  23. " <color>7f00ff00</color>\n"
  24. " </PolyStyle>\n"
  25. " </Style>\n"
  26. " <Placemark>\n"
  27. " <name>Path 1</name>\n"
  28. " <description>Path 1</description>\n"
  29. " <styleUrl>#yellowLineGreenPoly</styleUrl>\n"
  30. " <LineString>\n"
  31. " <tessellate>1</tessellate>\n"
  32. " <extrude>1</extrude>\n"
  33. " <altitudeMode>absolute</altitudeMode>\n"
  34. " <coordinates>\n";
  35. if(!storage_file_write(kml->file, kml_intro, strlen(kml_intro))) {
  36. FURI_LOG_E(TAG, "failed to write KML starting header!");
  37. storage_file_close(kml->file);
  38. storage_file_free(kml->file);
  39. return false;
  40. }
  41. // keeps track of writes for periodic flushes
  42. kml->write_counter = 0;
  43. FURI_LOG_I(TAG, "file opened successfully");
  44. return true;
  45. }
  46. bool kml_add_path_point(KMLFile* kml, double lat, double lon, uint32_t alt) {
  47. // KML is longitude then latitude for some reason
  48. FuriString* point = furi_string_alloc_printf(" %f,%f,%lu\n", lon, lat, alt);
  49. if(!storage_file_write(kml->file, furi_string_get_cstr(point), furi_string_size(point))) {
  50. FURI_LOG_E(TAG, "failed to write line to KML file!");
  51. return false;
  52. }
  53. furi_string_free(point);
  54. kml->write_counter += 1;
  55. if (kml->write_counter == 16) {
  56. if (!storage_file_sync(kml->file)) {
  57. FURI_LOG_E(TAG, "failed to periodic flush file!");
  58. }
  59. // reset
  60. kml->write_counter = 0;
  61. }
  62. return true;
  63. }
  64. bool kml_close_file(KMLFile* kml) {
  65. const char* kml_outro = " </coordinates>\n"
  66. " </LineString>\n"
  67. " </Placemark>\n"
  68. " </Document>\n"
  69. "</kml>";
  70. if(!storage_file_write(kml->file, kml_outro, strlen(kml_outro))) {
  71. FURI_LOG_E(TAG, "failed to close KML file!");
  72. storage_file_close(kml->file);
  73. storage_file_free(kml->file);
  74. return false;
  75. }
  76. storage_file_close(kml->file);
  77. storage_file_free(kml->file);
  78. return true;
  79. }