]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.imports/src/org/simantics/district/imports/DistrictImportUtils.java
Support for new edge properties in district import wizard
[simantics/district.git] / org.simantics.district.imports / src / org / simantics / district / imports / DistrictImportUtils.java
1 package org.simantics.district.imports;
2
3 import java.io.IOException;
4 import java.io.Reader;
5 import java.nio.charset.Charset;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.Iterator;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Optional;
16 import java.util.Set;
17 import java.util.concurrent.atomic.AtomicInteger;
18 import java.util.function.Function;
19
20 import org.apache.commons.csv.CSVFormat;
21 import org.apache.commons.csv.CSVParser;
22 import org.apache.commons.csv.CSVRecord;
23 import org.geotools.geometry.DirectPosition2D;
24 import org.geotools.referencing.CRS;
25 import org.opengis.geometry.DirectPosition;
26 import org.opengis.geometry.MismatchedDimensionException;
27 import org.opengis.referencing.FactoryException;
28 import org.opengis.referencing.NoSuchAuthorityCodeException;
29 import org.opengis.referencing.crs.CoordinateReferenceSystem;
30 import org.opengis.referencing.operation.MathTransform;
31 import org.opengis.referencing.operation.TransformException;
32 import org.simantics.Simantics;
33 import org.simantics.databoard.Bindings;
34 import org.simantics.db.Resource;
35 import org.simantics.db.WriteGraph;
36 import org.simantics.db.common.request.WriteRequest;
37 import org.simantics.db.exception.DatabaseException;
38 import org.simantics.db.layer0.util.Layer0Utils;
39 import org.simantics.district.network.DNEdgeBuilder;
40 import org.simantics.district.network.DistrictNetworkUtil;
41 import org.simantics.district.network.ontology.DistrictNetworkResource;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import com.vividsolutions.jts.index.quadtree.Quadtree;
46
47 public class DistrictImportUtils {
48
49     private DistrictImportUtils() { }
50
51     private static final Logger LOGGER = LoggerFactory.getLogger(DistrictImportUtils.class);
52     
53     public static Resource importCSVAsLayer(Path csvFile) throws IOException {
54         
55         try (CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(Files.newBufferedReader(csvFile))) {
56             Map<String, Integer> header = parser.getHeaderMap();
57             System.out.println(header);
58         }
59         return null;
60     }
61     
62     public static Map<String, Integer> readCSVHeader(Path source, char delimiter, boolean firstAsHeader) throws IOException {
63         return readCSVHeader(source, CSVFormat.newFormat(delimiter), firstAsHeader);
64     }
65     
66     public static Map<String, Integer> readCSVHeader(Path source, CSVFormat format, boolean firstAsHeader) throws IOException {
67         if (firstAsHeader)
68             format = format.withFirstRecordAsHeader();
69         try (CSVParser parser = format.parse(Files.newBufferedReader(source, Charset.defaultCharset()))) {
70             return parser.getHeaderMap();
71         }
72     }
73
74     public static Map<String, Character> getSupportedCSVDelimiterFormats() {
75         Map<String, Character> delimiters = new HashMap<>();
76         delimiters.put("Comma", ',');
77         delimiters.put("Semicolon", ';');
78         delimiters.put("Tabulator", '\t');
79         return delimiters;
80     }
81
82     public static List<Map<String, String>> readRows(Path source, CSVFormat format, boolean firstAsHeader, int amount) throws IOException {
83         if (firstAsHeader)
84             format = format.withFirstRecordAsHeader();
85         try (CSVParser parser = format.parse(Files.newBufferedReader(source))) {
86             int start = 0;
87             List<Map<String, String>> results = new ArrayList<>(amount);
88             Iterator<CSVRecord> iter = parser.iterator();
89             while (start < amount && iter.hasNext()) {
90                 CSVRecord record = iter.next();
91                 results.add(record.toMap());
92                 start++;
93             }
94             return results;
95         }
96     }
97
98     public static List<CSVRecord> readRows(Path source, char delim, boolean firstAsHeader, int rowAmount) throws IOException {
99         List<CSVRecord> results = new ArrayList<>();
100         AtomicInteger count = new AtomicInteger(0);
101         consumeCSV(source, delim, firstAsHeader, t -> {
102             results.add(t);
103             int current = count.incrementAndGet();
104             return current < rowAmount;
105         });
106         return results;
107     }
108     
109     public static void consumeCSV(Path source, char delim, boolean firstAsHeader, Function<CSVRecord, Boolean> consumer) throws IOException {
110         consumeCSV(Files.newBufferedReader(source), delim, firstAsHeader, consumer);
111     }
112
113     public static void consumeCSV(Reader reader, char delim, boolean firstAsHeader,
114             Function<CSVRecord, Boolean> consumer) throws IOException {
115         CSVFormat format = CSVFormat.newFormat(delim).withQuote('"');
116         if (firstAsHeader) {
117             format = format.withFirstRecordAsHeader();
118         }
119         try (CSVParser parser = format.parse(reader)) {
120             Iterator<CSVRecord> records = parser.iterator();
121             while (records.hasNext()) {
122                 Boolean cont = consumer.apply(records.next());
123                 if (!cont) {
124                     break;
125                 }
126             }
127         }
128     }
129
130     
131     public static Map<CSVHeader, List<String>> readCSVHeaderAndRows(Path source, char delimiter, boolean firstAsHeader, int amount) throws IOException {
132         Map<CSVHeader, List<String>> results = new HashMap<>();
133         CSVFormat format = CSVFormat.newFormat(delimiter);
134         if (firstAsHeader)
135             format = format.withFirstRecordAsHeader();
136         try (CSVParser parser = format.parse(Files.newBufferedReader(source))) {
137             Map<String, Integer> headers = parser.getHeaderMap();
138             if (headers != null && !headers.isEmpty()) {
139                 for (int index = 0; index < headers.size(); index++) {
140                     for (String head : headers.keySet()) {
141                         results.put(new CSVHeader(head, index), new ArrayList<>());
142                     }
143                 }
144             }
145             
146             Iterator<CSVRecord> records = parser.iterator();
147             int rows = 0;
148             while (rows < amount && records.hasNext()) {
149                 CSVRecord record = records.next();
150                 for (int j = 0; j < record.size(); j++) {
151                     String value = record.get(j);
152                     String header = Integer.toString(j);
153                     CSVHeader csvHeader = new CSVHeader(header, j);
154                     List<String> vals = results.get(csvHeader);
155                     if (vals == null) {
156                         vals = new ArrayList<>();
157                         results.put(csvHeader, vals);
158                     }
159                     vals.add(value);
160                 }
161                 rows++;
162             }
163         }
164         return results;
165     }
166     
167     public static class CSVHeader {
168
169         private final String header;
170         private final int index;
171         
172         public CSVHeader(String header, int index) {
173             this.header = header;
174             this.index = index;
175         }
176
177         public String getHeader() {
178             return header;
179         }
180
181         public int getIndex() {
182             return index;
183         }
184         
185         @Override
186         public int hashCode() {
187             final int prime = 31;
188             int result = 1;
189             result = prime * result + ((header == null) ? 0 : header.hashCode());
190             result = prime * result + index;
191             return result;
192         }
193
194         @Override
195         public boolean equals(Object obj) {
196             if (this == obj)
197                 return true;
198             if (obj == null)
199                 return false;
200             if (getClass() != obj.getClass())
201                 return false;
202             CSVHeader other = (CSVHeader) obj;
203             if (header == null) {
204                 if (other.header != null)
205                     return false;
206             } else if (!header.equals(other.header))
207                 return false;
208             if (index != other.index)
209                 return false;
210             return true;
211         }
212     }
213
214     public static Collection<String> readDistinctValuesOfColumn(Path source, char delim, int mappingIndex) throws IOException {
215         Set<String> results = new HashSet<>();
216         CSVFormat format = CSVFormat.newFormat(delim);
217         try (CSVParser parser = format.parse(Files.newBufferedReader(source))) {
218             Iterator<CSVRecord> records = parser.iterator();
219             if (records.hasNext())
220                 records.next();
221             while (records.hasNext()) {
222                 CSVRecord row = records.next();
223                 String value = row.get(mappingIndex);
224                 results.add(value);
225             }
226         }
227         return results;
228     }
229
230     public static void importVertices(CSVImportModel model) throws NoSuchAuthorityCodeException, FactoryException, DatabaseException {
231
232         Path csvFile = model.getSource();
233         char delim = model.getDelimiter();
234
235         int xCoordColumnIndex = model.getXCoordIndex();
236         int yCoordColumnIndex = model.getYCoordIndex();
237         int zCoordColumnIndex = model.getZCoordIndex();
238         int altElevationIndex = model.getAlternativeElevationIndex();
239         int supplyTempColumnIndex = model.getSupplyTempIndex();
240         int returnTempColumnIndex = model.getReturnTempIndex();
241         int supplyPressureColumnIndex = model.getSupplyPressureIndex();
242         int returnPressureColumnIndex = model.getReturnPressureIndex();
243         int dpIndex = model.getDeltaPressureIndex();
244         int dtIndex = model.getDeltaTemperatureIndex();
245         int heatPowerIndex = model.getHeatPowerIndex();
246         int peakPowerIndex = model.getPeakPowerIndex();
247         int valvePositionIndex = model.getValvePositionIndx();
248         int nominalHeadMIndex = model.getNominalHeadMIndex();
249         int nominalHeadBIndex = model.getNominalHeadBIndex();
250         int nominalFlowIndex = model.getNominalFlowIndex();
251         int maximumHeadMIndex = model.getMaximumHeadMIndex();
252         int heatLoadDsIndex = model.getHeatLoadDsIndex();
253         int massFlowIndex = model.getMassFlowIndex();
254         int volFlowIndex = model.getVolFlowIndex();
255         int velocityIndex = model.getVelocityIndex();
256         int flowAreaIndex = model.getFlowAreaIndex();
257         int nominalPressureLossIndex = model.getNominalPressureLossIndex();
258         int addressIndex = model.getAddressIndex();
259         int regionIndex = model.getRegionIndex();
260         
261         int mappingColumn = model.getComponentMappingIndex();
262         int idColumn = model.getIdIndex();
263         
264         String sourceEPSGCRS = model.getSourceCRS();
265         
266         MathTransform transform = null;
267         boolean doTransform = false;
268         // if sourceEPSGCRS is empty || null then ignore transformation
269         if (sourceEPSGCRS != null && !sourceEPSGCRS.isEmpty()) {
270             CoordinateReferenceSystem sourceCRS = CRS.decode(sourceEPSGCRS);
271             CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
272             transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
273             doTransform = true;
274         }
275         final boolean actualDoTransform = doTransform;
276         final MathTransform actualTransform = transform;
277         
278         Simantics.getSession().syncRequest(new WriteRequest() {
279             
280             @Override
281             public void perform(WriteGraph graph) throws DatabaseException {
282                 try {
283                     Layer0Utils.setDependenciesIndexingDisabled(graph, true);
284                     graph.markUndoPoint();
285                     
286                     DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
287
288                     DistrictImportUtils.consumeCSV(csvFile, delim, true, (Function<CSVRecord, Boolean>) row -> {
289                         try {
290                             String mappingValue = row.get(mappingColumn);
291                             
292                             String xCoords = row.get(xCoordColumnIndex);
293                             String yCoords = row.get(yCoordColumnIndex);
294                             double xCoord = Double.parseDouble(xCoords);
295                             double yCoord = Double.parseDouble(yCoords);
296                             
297                             double z = 0;
298                             if (zCoordColumnIndex != -1) {
299                                 String zs = row.get(zCoordColumnIndex);
300                                 
301                                 if (!zs.isEmpty()) {
302                                     try {
303                                         z = Double.parseDouble(zs);
304                                     } catch (NumberFormatException e1) {
305                                         throw new DatabaseException(e1);
306                                     }
307                                 }
308                             }
309                             
310                             double[] coords;
311                             if (actualDoTransform) {
312                                 DirectPosition2D targetPos = new DirectPosition2D();
313                                 DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord);
314                                 DirectPosition res = actualTransform.transform(sourcePos, targetPos);
315                                 coords = res.getCoordinate();
316                             } else {
317                                 coords = new double[] { xCoord, yCoord };
318                             }
319                             
320                             // Switch to (longitude, latitude)
321                             flipAxes(coords);
322                             
323                             Resource vertex = DistrictNetworkUtil.createVertex(graph, model.getParentDiagram(), coords, z, model.getComponentMappings().get(mappingValue));
324                             
325                             writeStringValue(graph, row, idColumn, vertex, DN.HasId);
326                             
327                             writeValue(graph, row, altElevationIndex, vertex, DN.Vertex_HasAltElevation);
328                             
329                             writeValue(graph, row, supplyTempColumnIndex, vertex, DN.Vertex_HasSupplyTemperature);
330                             writeValue(graph, row, returnTempColumnIndex, vertex, DN.Vertex_HasReturnTemperature);
331                             writeValue(graph, row, supplyPressureColumnIndex, vertex, DN.Vertex_HasSupplyPressure);
332                             writeValue(graph, row, returnPressureColumnIndex, vertex, DN.Vertex_HasReturnPressure);
333                             writeValue(graph, row, dpIndex, vertex, DN.Vertex_HasDeltaPressure);
334                             writeValue(graph, row, dtIndex, vertex, DN.Vertex_HasDeltaTemperature);
335                             writeValue(graph, row, heatPowerIndex, vertex, DN.Vertex_HasHeatPower);
336                             writeValue(graph, row, peakPowerIndex, vertex, DN.Vertex_HasPeakPower);
337                             writeValue(graph, row, valvePositionIndex, vertex, DN.Vertex_HasValvePosition);
338                             writeValue(graph, row, nominalHeadMIndex, vertex, DN.Vertex_HasNominalHeadM);
339                             writeValue(graph, row, nominalHeadBIndex, vertex, DN.Vertex_HasNominalHeadB);
340                             writeValue(graph, row, nominalFlowIndex, vertex, DN.Vertex_HasNominalFlow);
341                             writeValue(graph, row, maximumHeadMIndex, vertex, DN.Vertex_HasMaximumHeadM);
342                             writeValue(graph, row, heatLoadDsIndex, vertex, DN.Vertex_HasHeatLoadDs);
343                             writeValue(graph, row, massFlowIndex, vertex, DN.Vertex_HasMassFlow);
344                             writeValue(graph, row, volFlowIndex, vertex, DN.Vertex_HasVolFlow);
345                             writeValue(graph, row, velocityIndex, vertex, DN.Vertex_HasVelocity);
346                             writeValue(graph, row, flowAreaIndex, vertex, DN.Vertex_HasFlowArea);
347                             writeValue(graph, row, nominalPressureLossIndex, vertex, DN.Vertex_HasNominalPressureLoss);
348                             writeStringValue(graph, row, addressIndex, vertex, DN.Vertex_HasAddress);
349                             writeStringValue(graph, row, regionIndex, vertex, DN.HasRegion);
350                         } catch (DatabaseException | MismatchedDimensionException | TransformException e) {
351                             throw new RuntimeException(e);
352                         }
353                         return true;
354                     });
355                     
356                 } catch (IOException e) {
357                     LOGGER.error("Could not import", e);
358                     throw new DatabaseException(e);
359                 } finally {
360                     Layer0Utils.setDependenciesIndexingDisabled(graph, false);
361                 }
362             }
363         });
364     }
365
366     public static void importEdges(CSVImportModel model) throws NoSuchAuthorityCodeException, FactoryException, DatabaseException {
367
368         Path csvFile = model.getSource();
369         char delim = model.getDelimiter();
370
371         Set<String> writtenIds = new HashSet<>();
372         
373         int startXCoordColumnIndex = model.getStartXCoordIndex();
374         int startYCoordColumnIndex = model.getStartYCoordIndex();
375         int startZValueColumnIndex = model.getStartZCoordIndex();
376         int endXCoordColumnIndex = model.getEndXCoordIndex();
377         int endYCoordColumnIndex = model.getEndYCoordIndex();
378         int endZValueColumnIndex = model.getEndZCoordIndex();
379         int diameterColumnIndex= model.getDiameterIndex();
380         int outerDiameterColumnIndex = model.getOuterDiamterIndex();
381         int nominalMassFlowIndex = model.getNominalMassFlowIndex();
382         int tGroundIndex = model.gettGroundIndex();
383         int edgeFlowAreaIndex = model.getEdgeFlowAreaIndex();
384         int kReturnIndex = model.getkReturnIndex();
385         int kSupplyIndex = model.getkSupplyIndex();
386         int lengthIndex = model.getLengthIndex();
387         int detailedGeometryIndex = model.getDetailedGeometryIndex();
388         int regionIndex = model.getRegionIndex();
389         int pipeTypeIndex = model.getPipeTypeIndex();
390         int pipeCodeIndex = model.getPipeCodeIndex();
391         int installationYearIndex = model.getInstallationYearIndex();
392         int wallThicknessIndex = model.getWallThicknessIndex();
393         int insulationConductivityIndex = model.getInsulationConductivityIndex();
394         int pipeSizeDNIndex = model.getPipeSizeDNIndex();
395         int roughnessIndex = model.getRoughnessIndex();
396         int structureIndex = model.getStructureIndex();
397         
398         int mappingColumn = model.getComponentMappingIndex();
399         int idColumn = model.getIdIndex();
400         
401         double padding = model.getEdgePadding();
402
403         String sourceEPSGCRS = model.getSourceCRS();
404         
405         MathTransform transform = null;
406         boolean doTransform = false;
407         // if sourceEPSGCRS is empty || null then ignore transformation
408         if (sourceEPSGCRS != null && !sourceEPSGCRS.isEmpty()) {
409             CoordinateReferenceSystem sourceCRS = CRS.decode(sourceEPSGCRS);
410             CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
411             transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
412             doTransform = true;
413         }
414         final boolean actualDoTransform = doTransform;
415         final MathTransform actualTransform = transform;
416         
417         double halfPadding = padding / 2;
418         
419         Quadtree existingVertices = DistrictNetworkUtil.existingVertices(model.getParentDiagram(), halfPadding);
420
421         Simantics.getSession().syncRequest(new WriteRequest() {
422             
423             @Override
424             public void perform(WriteGraph graph) throws DatabaseException {
425                 try {
426                     Layer0Utils.setDependenciesIndexingDisabled(graph, true);
427                     graph.markUndoPoint();
428
429                     DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
430                     
431                     DistrictImportUtils.consumeCSV(csvFile, delim, true, row -> {
432                         try {
433                             
434                             String idValue = row.get(idColumn);
435                             if (!writtenIds.contains(idValue)) {
436                                 writtenIds.add(idValue);
437                                 String mappingValue = row.get(mappingColumn);
438                                 
439                                 String startXCoords = row.get(startXCoordColumnIndex);
440                                 String startYCoords = row.get(startYCoordColumnIndex);
441                                 String startZCoords = row.get(startZValueColumnIndex);
442                                 String endXCoords = row.get(endXCoordColumnIndex);
443                                 String endYCoords = row.get(endYCoordColumnIndex);
444                                 String endZCoords = row.get(endZValueColumnIndex);
445                                 
446                                 double startXCoord = Double.parseDouble(startXCoords); // make negative
447                                 double startYCoord = Double.parseDouble(startYCoords);
448                                 double startZCoord = Double.parseDouble(startZCoords);
449                                 
450                                 double endXCoord = Double.parseDouble(endXCoords); // make negative
451                                 double endYCoord = Double.parseDouble(endYCoords);
452                                 double endZCoord = Double.parseDouble(endZCoords);
453                                 
454                                 double[] startCoords;
455                                 double[] endCoords;
456                                 if (actualDoTransform) {
457                                     DirectPosition2D startTargetPos = new DirectPosition2D();
458                                     DirectPosition2D startSourcePos = new DirectPosition2D(startXCoord, startYCoord);
459                                     DirectPosition startRes = actualTransform.transform(startSourcePos, startTargetPos);
460                                     startCoords = startRes.getCoordinate();
461                                     
462                                     DirectPosition2D endTargetPos = new DirectPosition2D();
463                                     DirectPosition2D endSourcePos = new DirectPosition2D(endXCoord, endYCoord);
464                                     DirectPosition endRes = actualTransform.transform(endSourcePos, endTargetPos);
465                                     endCoords = endRes.getCoordinate();
466                                 } else {
467                                     startCoords = new double[] { startXCoord , startYCoord };
468                                     endCoords = new double[] { endXCoord , endYCoord };
469                                 }
470                                 
471                                 // Switch to (longitude, latitude)
472                                 flipAxes(startCoords);
473                                 flipAxes(endCoords);
474                                 
475                                 Optional<Resource> oedge = DNEdgeBuilder.create(graph, existingVertices, model.getParentDiagram(), model.getComponentMappings().get(mappingValue), startCoords, startZCoord, endCoords, endZCoord, new double[0], padding, true);
476                                 if (oedge.isPresent()) {
477                                     Resource edge = oedge.get();
478                                     
479                                     writeStringValue(graph, row, idColumn, edge, DN.HasId);
480                                     
481                                     writeValue(graph, row, diameterColumnIndex, edge, DN.Edge_HasDiameter);
482                                     writeValue(graph, row, outerDiameterColumnIndex, edge, DN.Edge_HasOuterDiameter);
483                                     writeValue(graph, row, nominalMassFlowIndex, edge, DN.Edge_HasNominalMassFlow);
484                                     writeValue(graph, row, tGroundIndex, edge, DN.Edge_HasTGround);
485                                     writeValue(graph, row, kReturnIndex, edge, DN.Edge_HasKReturn);
486                                     writeValue(graph, row, kSupplyIndex, edge, DN.Edge_HasKSupply);
487                                     writeValue(graph, row, edgeFlowAreaIndex, edge, DN.Edge_HasFlowArea);
488                                     writeValue(graph, row, lengthIndex, edge, DN.Edge_HasLength);
489                                     writeStringValue(graph, row, regionIndex, edge, DN.HasRegion);
490                                     writeStringValue(graph, row, pipeTypeIndex, edge, DN.Edge_HasType);
491                                     writeDoubleArrayFromString(graph, row, detailedGeometryIndex, edge, DN.Edge_HasGeometry, actualTransform);
492                                     writeStringValue(graph, row, pipeCodeIndex, edge, DN.Edge_HasPipeCode);
493                                     writeIntegerValue(graph, row, installationYearIndex, edge, DN.Edge_HasInstallationYear);
494                                     writeValue(graph, row, wallThicknessIndex, edge, DN.Edge_HasWallThickness);
495                                     writeValue(graph, row, insulationConductivityIndex, edge, DN.Edge_HasInsulationConductivity);
496                                     writeIntegerValue(graph, row, pipeSizeDNIndex, edge, DN.Edge_HasPipeSizeDN);
497                                     writeValue(graph, row, roughnessIndex, edge, DN.Edge_HasRoughness);
498                                     writeStringValue(graph, row, structureIndex, edge, DN.Edge_HasStructure);
499                                 }
500                             }
501                             return true;
502                         } catch (DatabaseException | MismatchedDimensionException | TransformException e) {
503                             throw new RuntimeException(e);
504                         }
505                     });
506                 } catch (IOException e) {
507                     LOGGER.error("Could not import edges {}", model.getSource(), e);
508                 } finally {
509                     Layer0Utils.setDependenciesIndexingDisabled(graph, false);
510                 }
511             }
512         });
513     }
514     
515     private static void flipAxes(double[] coords) {
516         double tmp = coords[0];
517         coords[0] = coords[1];
518         coords[1] = tmp;
519     }
520
521     private static void writeValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException {
522         if (index != -1) {
523             String stringValue = row.get(index);
524             if (!stringValue.isEmpty()) {
525                 try {
526                     if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) {
527                         stringValue = stringValue.substring(1, stringValue.length() - 1);
528                     }
529                     graph.claimLiteral(subject, relation, Double.parseDouble(stringValue), Bindings.DOUBLE);
530                 } catch (NumberFormatException e) {
531                     LOGGER.error("Could not parse {} {} {} {}", row, index, subject, relation, e);
532                     //throw new DatabaseException(e);
533                 }
534             }
535         }
536     }
537     
538     private static void writeIntegerValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException {
539         if (index != -1) {
540             String stringValue = row.get(index);
541             if (!stringValue.isEmpty()) {
542                 try {
543                     if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) {
544                         stringValue = stringValue.substring(1, stringValue.length() - 1);
545                     }
546                     graph.claimLiteral(subject, relation, Integer.parseInt(stringValue), Bindings.INTEGER);
547                 } catch (NumberFormatException e) {
548                     LOGGER.error("Could not parse {} {} {} {}", row, index, subject, relation, e);
549                     //throw new DatabaseException(e);
550                 }
551             }
552         }
553     }
554     
555     private static void writeStringValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException {
556         if (index != -1) {
557             String stringValue = row.get(index);
558             if (!stringValue.isEmpty()) {
559                 try {
560                     graph.claimLiteral(subject, relation, stringValue, Bindings.STRING);
561                 } catch (NumberFormatException e) {
562                     throw new DatabaseException(e);
563                 }
564             }
565         }
566     }
567
568     private static void writeDoubleArrayFromString(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation, MathTransform actualTransform) throws DatabaseException, MismatchedDimensionException, TransformException {
569         if (index != -1) {
570             String stringValue = row.get(index);
571             if (!stringValue.isEmpty()) {
572                 if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) {
573                     stringValue = stringValue.substring(1, stringValue.length() - 1);
574                 }
575                 String[] coordPairs = stringValue.split(";");
576                 ArrayList<Double> dd = new ArrayList<>(coordPairs.length * 2);
577                 for (int i = 0; i < coordPairs.length; i++) {
578                     String coordPair = coordPairs[i];
579                     String[] p = coordPair.split(" ");
580                     double x = Double.parseDouble(p[0]);
581                     double y = Double.parseDouble(p[1]);
582                     if (actualTransform != null) {
583                         DirectPosition2D targetPos = new DirectPosition2D();
584                         DirectPosition2D sourcePos = new DirectPosition2D(y, x);
585                         DirectPosition res = actualTransform.transform(sourcePos, targetPos);
586                         double[] coords = res.getCoordinate();
587                         x = coords[1];
588                         y = coords[0];
589                     }
590                     dd.add(x);
591                     dd.add(y);
592                 }
593                 double[] detailedGeometryCoords = new double[dd.size()];
594                 for (int i = 0; i < dd.size(); i++) {
595                     double d = dd.get(i);
596                     detailedGeometryCoords[i] = d;
597                 }
598                 try {
599                     graph.claimLiteral(subject, relation, detailedGeometryCoords, Bindings.DOUBLE_ARRAY);
600                 } catch (NumberFormatException e) {
601                     throw new DatabaseException(e);
602                 }
603             }
604         }
605     }
606 }