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
148 lines
6.1 KiB
C
2 years ago
|
// 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_
|