// Copyright 2010, Google Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // 3. Neither the name of Google Inc. nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file contains the declaration of the CsvParser class. #ifndef KML_CONVENIENCE_CSV_PARSER_H_ #define KML_CONVENIENCE_CSV_PARSER_H_ #include "kml/base/string_util.h" #include "kml/dom.h" namespace kmlbase { class CsvSplitter; } namespace kmlconvenience { enum CsvParserStatus { CSV_PARSER_STATUS_OK = 0, CSV_PARSER_STATUS_BLANK_LINE, CSV_PARSER_STATUS_NO_LAT_LON, CSV_PARSER_STATUS_BAD_LAT_LON, CSV_PARSER_STATUS_INVALID_DATA, CSV_PARSER_STATUS_COMMENT }; // This class is used as the output and error reporting mechanism for the // CsvParser. Application code should subclass this and implement HandleLine. // This "default" implementation acts as a data sink. class CsvParserHandler { public: virtual ~CsvParserHandler() {} // This method is called for each line in the CSV data. The line is the line // number of the CSV. The status indicates the success of creating // a KML Point Placemark from the CSV line. A Placemark is always created // but it may be devoid of children depending on the strictness state of // CsvParser. In strict mode CSV_PARSER_STATUS_OK indicates the Placemark // has at least a Point with lat and lon. The caller takes ownership of // the placemark. The return value indicates if CSV parsing is to continue // to the next line in the file. Returning false immediately halts all // further processing of the CsvParse. virtual bool HandleLine(int line, CsvParserStatus status, kmldom::PlacemarkPtr placemark) { return true; // Always continue to the next line. } }; // This class converts CSV data to KML. Overall usage: // CsvSplitter csv_splitter(csv_data); // class YourCsvParserHandler : public CsvParserHandler { // public: // virtual bool HandleLine(int line, CsvParserStatus status, // kmldom::PlacemarkPtr placemark) { // ...inspect status and/or save/process placemark... // return true; // Or false to stop CSV parsing. // } // }; // YourCsvParserHandler your_csv_parser_handler; // CsvParser::ParseCsv(&csv_splitter, &your_csv_parser_handler); class CsvParser { public: // This method uses CsvSplitter to split each line which CsvParser converts // to KML which is handed to the CsvParserHandler. static bool ParseCsv(kmlbase::CsvSplitter* csv_splitter, CsvParserHandler* csv_parser_handler); // All of the below should really be private. // Use the static ParseCsv method. CsvParser(kmlbase::CsvSplitter* csv_splitter, CsvParserHandler* csv_parser_handler); // This gets the internal CSV schema. typedef std::map CsvSchema; const CsvSchema& GetSchema() const { return csv_schema_; } // This internal method sets the schema for subsequent lines of CSV data. // This sets the mappings from column to field. Here is how the data for // each column is used. VAL is substituted for the value in the cell: // name - VAL // feature-id - // description - VAL // style-id - style.kml#style-VAL // latitude - xxx,VAL // longitude - VAL,xxx // other - VAL // # - comment causes CSV_PARSER_STATUS_COMMENT for that line // The "latitude" and "longitude" columns specify which columns are used // for the latitude and longitude of the . All other columns specify // / names. The csv_schema must contain at least // "latitude" and "longitude". Any schema term may be mixed case. CsvParserStatus SetSchema(const kmlbase::StringVector& csv_schema); // This internal method sets the fields of the given placemark from the // csv_line as per the state of the csv schema. The csv_line size must // match the CSV schema. CsvParserStatus CsvLineToPlacemark(kmlbase::StringVector& csv_line, kmldom::PlacemarkPtr placemark) const; // This internal method iterates over each line using the CsvSplitter and // and passes the created KML to the CsvParserHandler. bool ParseCsvData(); private: kmlbase::CsvSplitter* csv_splitter_; CsvParserHandler* csv_parser_handler_; size_t schema_size_; size_t name_col_; size_t description_col_; size_t lat_col_; size_t lon_col_; size_t feature_id_; size_t style_id_; string style_url_base_; kmldom::KmlFactory* kml_factory_; CsvSchema csv_schema_; LIBKML_DISALLOW_EVIL_CONSTRUCTORS(CsvParser); }; } // end namespace kmlconvenience #endif // KML_CONVENIENCE_CSV_PARSER_H_