core/kml.c

00001 
00014 #include <string.h>
00015 #include <stdio.h>
00016 #include <errno.h>
00017 #include <time.h>
00018 #include "class.h"
00019 #include "object.h"
00020 #include "output.h"
00021 #include "exception.h"
00022 #include "module.h"
00023 
00024 #include "kml.h"
00025 
00026 int kml_document(FILE *fp)
00027 {
00028     CLASS *oclass, *openclass=NULL;
00029     MODULE *mod;
00030     char buffer[1024];
00031     time_t now = time(NULL);
00032     fprintf(fp,"  <Document>\n");
00033     fprintf(fp,"    <name>%s</name>\n", global_modelname);
00034     fprintf(fp,"    <description>GridLAB-D results for %s</description>\n",
00035         convert_from_timestamp(global_clock,buffer,sizeof(buffer))?buffer:"unknown date/time");
00036 
00037     /* for each module */
00038     for (mod=module_get_first(); mod!=NULL; mod=mod->next)
00039     {
00040         if (mod->kmldump)
00041             mod->kmldump(fp,NULL); /* dump styles */
00042     }
00043 
00044     /* scan each class in the model */
00045     for (oclass=class_get_first_class(); oclass!=NULL; oclass=oclass->next)
00046     {
00047         OBJECT *obj;
00048 
00049         /* scan each object in the model */
00050         for (obj=object_get_first(); obj!=NULL; obj=obj->next)
00051         {
00052             int has_location = !(isnan(obj->latitude) || isnan(obj->longitude));
00053             MODULE *mod;
00054 
00055             /* class does not match current object */
00056             if (obj->oclass!=oclass)
00057                 continue;
00058 
00059             /* first instance of this class needs folder */
00060             else if (openclass==NULL)
00061             {
00062                 fprintf(fp,"  <Folder><name>Class %s</name>\n", oclass->name);
00063                 fprintf(fp,"    <description>Module %s",oclass->module->name);
00064                 if (oclass->module->minor!=0 || oclass->module->major!=0)
00065                     fprintf(fp," (V%d.%02d)",oclass->module->major,oclass->module->minor);
00066                 fprintf(fp,"</description>\n",oclass->module->name);
00067                 openclass=oclass;
00068             }           
00069 
00070             /* module overrides KML output */
00071             mod = (MODULE*)(obj->oclass->module);
00072             if (mod->kmldump!=NULL)
00073                 (*(mod->kmldump))(fp,obj);
00074             else if (has_location)
00075             {
00076                 /* basic KML output of published variables */
00077                 PROPERTY *prop;
00078                 fprintf(fp,"    <Placemark>\n");
00079                 if (obj->name)
00080                     fprintf(fp,"      <name>%s</name>\n", obj->name);
00081                 else
00082                     fprintf(fp,"      <name>%s %d</name>\n", obj->oclass->name, obj->id);
00083                 fprintf(fp,"      <description>\n");
00084                 fprintf(fp,"        <![CDATA[\n");
00085                 fprintf(fp,"          <TABLE><TR>\n");
00086                 for (prop=oclass->pmap;prop!=NULL && prop->otype==oclass->type;prop=prop->next)
00087                 {
00088                     char *value = object_property_to_string(obj,prop->name);
00089                     if (value!=NULL)
00090                         fprintf(fp,"<TR><TH ALIGN=LEFT>%s</TH><TD ALIGN=RIGHT>%s</TD></TR>",
00091                             prop->name, value);
00092                 }
00093                 fprintf(fp,"          </TR></TABLE>\n");
00094                 fprintf(fp,"        ]]>\n");
00095                 fprintf(fp,"      </description>\n");
00096                 fprintf(fp,"      <Point>\n");
00097                 fprintf(fp,"        <coordinates>%f,%f</coordinates>\n",obj->longitude,obj->latitude);
00098                 fprintf(fp,"      </Point>\n");
00099                 fprintf(fp,"    </Placemark>\n");
00100             }
00101         }
00102 
00103         /* close folder if any */
00104         if (openclass!=NULL)
00105         {
00106             fprintf(fp,"  </Folder>\n");
00107             openclass=NULL;
00108         }
00109     }
00110 
00111     fprintf(fp,"  </Document>\n");
00112     return 0;
00113 }
00114 
00115 int kml_output(FILE *fp)
00116 {
00117     fprintf(fp,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00118     fprintf(fp,"<kml xmlns=\"http://earth.google.com/kml/2.2\">\n");
00119     kml_document(fp);
00120     fprintf(fp,"</kml>\n");
00121     return 0;
00122 }
00123 
00124 int kml_dump(char *filename)
00125 {
00126     char *ext, *basename;
00127     size_t b;
00128     char fname[1024];
00129     FILE *fp;
00130 
00131     /* handle default filename */
00132     if (filename==NULL)
00133         filename="gridlabd.kml";
00134 
00135     /* find basename */
00136     b = strcspn(filename,"/\\:");
00137     basename = filename + (b<strlen(filename)?b:0);
00138 
00139     /* find extension */
00140     ext = strrchr(filename,'.');
00141 
00142     /* if extension is valid */
00143     if (ext!=NULL && ext>basename)
00144 
00145         /* use filename verbatim */
00146         strcpy(fname,filename);
00147 
00148     else
00149 
00150         /* append default extension */
00151         strcat(strcpy(fname,filename),".kml");
00152 
00153     /* open file */
00154     fp = fopen(fname,"w");
00155     if (fp==NULL)
00156         throw_exception("kml_dump(char *filename='%s'): %s", filename, strerror(errno));
00157 
00158     /* output data */
00159     kml_output(fp);
00160 
00161     /* close file */
00162     fclose(fp);
00163 
00164     return 0;
00165 }

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy