You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
6.1 KiB
C

// 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<int, string> 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 - <name>VAL</name>
// feature-id - <Placemark id="feature-VAL">
// description - <description>VAL</description>
// style-id - <styleUrl>style.kml#style-VAL</styleUrl>
// latitude - <Point><coordinates>xxx,VAL</coordinates></Point>
// longitude - <Point><coordinates>VAL,xxx</coordinates></Point>
// other - <Data name="other"><value>VAL</value></Data>
// # - 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 <Point>. All other columns specify
// <ExtendedData>/<Data> 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_