source: other-projects/maori-lang-detection/src/org/greenstone/atea/CountryCodeCountsMapData.java@ 33790

Last change on this file since 33790 was 33790, checked in by ak19, 4 years ago

Got the MultiPoint geojson mapdata of the country code counts working: the geojson mapdata now gets output and can be used at http://geojson.tools. Next time, will work on outputting complex geojson Feature objects: properties about country and count information and counts as histograms made from polygons.

File size: 10.0 KB
Line 
1package org.greenstone.atea;
2
3import java.io.*;
4
5import org.apache.commons.csv.*;
6import org.apache.log4j.Logger;
7
8import com.google.gson.*;
9
10import java.util.HashMap;
11import java.util.LinkedList;
12import java.util.List;
13import java.util.Map;
14
15// For working with GeoJSON's Simple Features in Java
16import mil.nga.sf.geojson.FeatureConverter;
17import mil.nga.sf.geojson.Geometry;
18import mil.nga.sf.geojson.MultiPoint;
19import mil.nga.sf.geojson.Position;
20
21
22/** Simple Features GeoJSON Java
23 * https://ngageoint.github.io/simple-features-geojson-java/ - liks to API and more
24 *
25 * https://mvnrepository.com/artifact/mil.nga.sf/sf-geojson (https://github.com/ngageoint/simple-features-geojson-java/)
26 *
27 * Also need the basic data types used by the Geometry objects above:
28 * https://mvnrepository.com/artifact/mil.nga/sf (https://github.com/ngageoint/simple-features-java)
29 *
30 * Further helper jars needed (because of encountering the exception documented at
31 * stackoverflow.com/questions/36278293/java-lang-classnotfoundexception-com-fasterxml-jackson-core-jsonprocessingexcep/36279872)
32 * https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.10.0
33 * https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
34 * https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations/2.10.0
35 */
36
37/**
38 * This class needs the gson library, and now the sf(-2.02).jar and sf-geojson(-2.02).jar files too
39 * to create and store Simple Features geo json objects with Java.
40 * I copied the gson jar file from GS3.
41 *
42 * TO COMPILE:
43 * maori-lang-detection/src$
44 * javac -cp ".:../conf:../lib/*" org/greenstone/atea/CountryCodeCountsMapData.java
45 *
46 * TO RUN:
47 * maori-lang-detection/src$
48 * java -cp ".:../conf:../lib/*" org/greenstone/atea/CountryCodeCountsMapData ../mongodb-data/countrycodes.json ../mongodb-data/counts.json
49 *
50 */
51public class CountryCodeCountsMapData {
52 static Logger logger = Logger.getLogger(org.greenstone.atea.CountryCodeCountsMapData.class.getName());
53
54 //Map<String, JsonObject> countryToJsonMap;
55 JsonArray countryCodesJsonArray;
56 JsonArray countryCountsJsonArray;
57
58 // North-central Antarctica coords
59 private final double ANTARCTICA_LNG = 57.0d;
60 private final double ANTARCTICA_LAT = -70.0d;
61 // For EU coords, spot in Atlantic Ocean close to western European coast.
62 private final double EU_LNG = -20.0d;
63 private final double EU_LAT = 50.0d;
64
65 public CountryCodeCountsMapData(String countryCoordsJSONFile, String countryCountsJSONFile) throws Exception {
66
67 // map of country codes to lat, lng json for that country code
68 Map<String, JsonObject> countryToJsonMap = new HashMap<String, JsonObject>();
69
70 // Parse json file of country codes and put into a JsonArray.
71 // then put into map of each country code to its JsonObject.
72 countryCodesJsonArray = parseJSONFile(countryCoordsJSONFile);
73 for(JsonElement obj : countryCodesJsonArray) {
74 JsonObject countryCodeJson = obj.getAsJsonObject();
75 countryToJsonMap.put(countryCodeJson.get("country").getAsString(), countryCodeJson);
76 }
77
78 // Parse json file of country code counts
79 // Then for each JsonObject in this file,
80 // find a match on its country code in the map created above to get a country code JsonObject
81 // Get the longitude and latitude of the JsonObject that matched that country code.
82 // Add this lng,lat location information to the current JsonObject from the counts file.
83 countryCountsJsonArray = parseJSONFile(countryCountsJSONFile);
84
85 for(JsonElement obj : countryCountsJsonArray) {
86 JsonObject json = obj.getAsJsonObject();
87 String countryCode = json.get("_id").getAsString();
88 int count = (int)json.get("count").getAsDouble();
89
90 //logger.info("Got country code: " + countryCode);
91 //logger.info(" count: " + count);
92
93 // locate in countryCode map
94 JsonObject countryCodeJson = countryToJsonMap.get(countryCode);
95
96 if(countryCodeJson != null) {
97 //logger.info("Found in map: " + countryCodeJson.toString());
98
99 // for geojson, want longitude then latitude
100 Double lng = countryCodeJson.get("longitude").getAsDouble();
101 Double lat = countryCodeJson.get("latitude").getAsDouble();
102 //logger.info("long: " + Double.toString(lng) + ", lat: " + Double.toString(lat));
103
104 // let's add lat and lng fields to countryCounts object
105 json.addProperty("lng", lng); // adds Number: https://javadoc.io/static/com.google.code.gson/gson/2.8.5/index.html?com/google/gson/Gson.html
106 json.addProperty("lat", lat);
107 } else {
108 logger.info("No geolocation info found for country code " + countryCode);
109 if(countryCode.equals("EU")) {
110 //logger.info("Unlisted country code: EU");
111 // add lat and lng for Europe
112 json.addProperty("lng", EU_LNG);
113 json.addProperty("lat", EU_LAT);
114 }
115 else if(countryCode.equals("UNKNOWN")) {
116 //logger.info("Unlisted country code: UNKNOWN");
117 // add lat and lng for Antarctica
118 json.addProperty("lng", ANTARCTICA_LNG);
119 json.addProperty("lat", ANTARCTICA_LAT);
120 } else {
121 logger.error("ERROR: entirely unknown country code: " + countryCode);
122 }
123 }
124 }
125
126 }
127
128 /** Convert mongodb tabular output of json records stored in the given file
129 * into a JsonArray.
130 */
131 public JsonArray parseJSONFile(String filename) throws Exception {
132 JsonArray jsonArray = null;
133 // read into string
134 try (
135 BufferedReader reader = new BufferedReader(new FileReader(filename));
136 ) {
137 StringBuilder str = //new StringBuilder();
138 new StringBuilder("[");
139 String line;
140 while((line = reader.readLine()) != null) {
141 line = line.replaceAll("/\\* [^\\/]* \\*/", "");
142 str.append(line);
143 if(line.endsWith("}")) {
144 str.append(",\n");
145 }
146 }
147 // replace last comma with closing bracket
148 String fileContents = str.substring(0, str.length()-2) + "]";
149
150 //System.err.println("Got file:\n" + fileContents);
151
152 // https://stackoverflow.com/questions/2591098/how-to-parse-json-in-java
153 jsonArray = new JsonParser().parse(fileContents).getAsJsonArray();
154
155 } catch(Exception e) {
156 throw e;
157 }
158
159
160 return jsonArray;
161 }
162
163 /**
164 * Reading
165 * https://www.here.xyz/api/concepts/geojsonbasics/
166 * https://ngageoint.github.io/simple-features-geojson-java/docs/api/
167 *
168 * https://stackoverflow.com/questions/55621480/cant-access-coordinates-member-of-geojson-feature-collection
169 *
170 * Downloaded geojson simple features' jar file from maven, but it didn't work:
171 * a more private version of MultiPoint.java is not included in the jar file (there's only
172 * mil.nga.sf.geojson.MultiPoint , whereas
173 * mil.nga.sf.MultiPoint is missing
174 *
175 * This seems to have gone wrong at
176 * https://github.com/ngageoint/simple-features-geojson-java/tree/master/src/main/java/mil/nga/sf
177 * but the one at
178 * https://github.com/ngageoint/simple-features-java/tree/master/src/main/java/mil/nga/sf
179 * has it. So I've been trying to build that, but don't have the correct version of maven.
180 */
181 public Geometry toMultiPointGeoJson() {
182 //System.err.println("toGeoJSON() is not yet implemented.");
183
184 List<Position> points = new LinkedList<Position>();
185
186 for(JsonElement obj : countryCountsJsonArray) {
187 JsonObject json = obj.getAsJsonObject();
188 Double lng = json.get("lng").getAsDouble();
189 Double lat = json.get("lat").getAsDouble();
190
191 Position point = new Position(lng, lat);
192 points.add(point);
193 }
194
195 Geometry multiPoint = new MultiPoint(points);
196
197 return multiPoint;
198 }
199
200
201 public String writeMultiPointGeoJsonToFile(File folder) {
202 final String filename = "multipoint.json";
203 File outFile = new File(folder, filename);
204
205 Geometry geometry = this.toMultiPointGeoJson();
206 String multiPointGeojsonString = FeatureConverter.toStringValue(geometry);
207 System.err.println("\nMap data as MultiPoint geometry:\n" + multiPointGeojsonString + "\n");
208 try (
209 Writer writer = new BufferedWriter(new FileWriter(outFile));
210 ) {
211
212 // Some basic re-formatting for some immediate legibility
213 // But pasting the contents of the file (or the System.err output above)
214 // directly into http://geojson.tools/ will instantly reformat the json perfectly anyway.
215 multiPointGeojsonString = multiPointGeojsonString.replace("[[", "\n[\n\t[");
216 multiPointGeojsonString = multiPointGeojsonString.replace("],[", "],\n\t[");
217 multiPointGeojsonString = multiPointGeojsonString.replace("]]", "]\n]");
218
219 writer.write(multiPointGeojsonString + "\n");
220 } catch(Exception e) {
221 logger.error("Unable to write multipoint geojson:\n**********************");
222 logger.error(multiPointGeojsonString);
223 logger.error("**********************\ninto file " + outFile.getAbsolutePath());
224 logger.error(e.getMessage(), e);
225 }
226
227 return outFile.getAbsolutePath();
228
229 }
230
231
232 // Unfinished and unused
233 public void parseCSVFile(String filename) throws Exception {
234 File csvData = new File(filename);
235 CSVParser parser = CSVParser.parse(csvData, java.nio.charset.Charset.forName("US-ASCII"), CSVFormat.RFC4180);
236 for (CSVRecord csvRecord : parser) {
237 logger.info("Got record: " + csvRecord.toString());
238 }
239 }
240
241 public static void printUsage() {
242 System.err.println("CountryCodeCountsMapData countrycodes.json counts.json");
243 }
244
245 public static void main(String args[]) {
246 if(args.length != 2) {
247 printUsage();
248 System.exit(-1);
249 }
250
251 try {
252 File countsFile = new File(args[1]);
253 File parentFolder = countsFile.getParentFile().getCanonicalFile(); // canonical resolves any .. and . in path
254
255 CountryCodeCountsMapData mapData = new CountryCodeCountsMapData(args[0], args[1]);
256
257 //Geometry geometry = mapData.toMultiPointGeoJSON();
258 //String multiPointGeojsonString = FeatureConverter.toStringValue(geometry);
259 //System.err.println("geometry: " + multiPointGeojsonString);
260
261 String outFileName = mapData.writeMultiPointGeoJsonToFile(parentFolder);
262 System.err.println("***********\nWrote mapdata to file " + outFileName);
263 } catch(Exception e) {
264 logger.error(e.getMessage(), e);
265 }
266 }
267}
Note: See TracBrowser for help on using the repository browser.