Project

General

Profile

Download (5.74 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2013 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package eu.etaxonomy.cdm.ext.geo;
10

    
11
import java.io.File;
12
import java.io.IOException;
13
import java.io.Reader;
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18

    
19
import org.apache.commons.lang.ArrayUtils;
20
import org.apache.log4j.Level;
21
import org.apache.log4j.Logger;
22

    
23
import au.com.bytecode.opencsv.CSVReader;
24
import eu.etaxonomy.cdm.model.common.TermVocabulary;
25
import eu.etaxonomy.cdm.model.location.NamedArea;
26

    
27
/**
28
 * Reads csv data containing the attributes from a shape file and adds the
29
 * shapefile data to each area in the given set of {@link NamedAreas}. The way
30
 * this data it attached to the areas is specific to the
31
 * {@link IGeoServiceAreaMapping} implementation. It is recommended to create
32
 * csv file directly from the original shape file by making use of the
33
 * {@code org2ogr} command which is contained in the <a
34
 * href="http://www.gdal.org/ogr2ogr.html">gdal</a> tools:
35
 *
36
 * <pre>
37
 * ogr2ogr -f csv out.csv input_shape_file.shp
38
 * </pre>
39
 *
40
 *
41
 * @author a.kohlbecker
42
 \* @since Oct 18, 2013
43
 *
44
 */
45
public class ShpAttributesToNamedAreaMapper {
46

    
47
    public static final Logger logger = Logger.getLogger(ShpAttributesToNamedAreaMapper.class);
48

    
49
    private static final char COMMA = ',';
50

    
51
    private final Set<NamedArea> areas;
52

    
53
    private final IGeoServiceAreaMapping areaMapping;
54

    
55
    /**
56
     * maps the idSearchFields supplied to the {@link #readCsv(File, List)} method to the
57
     * column index
58
     */
59
    private Map<String,Integer> searchColumnMap = null;
60

    
61
    public ShpAttributesToNamedAreaMapper(Set<NamedArea> areas, IGeoServiceAreaMapping areaMapping) {
62
        this.areas = areas;
63
        this.areaMapping = areaMapping;
64
    }
65

    
66
    public ShpAttributesToNamedAreaMapper(TermVocabulary<NamedArea> areaVocabulary, IGeoServiceAreaMapping areaMapping) {
67
        this.areas = areaVocabulary.getTerms();
68
        this.areaMapping = areaMapping;
69
    }
70

    
71
    /**
72
     * @param reader A reader of the csv data
73
     * @param idSearchFields
74
     *            An ordered list column names in the the csv file to be
75
     *            imported. These columns will be used to search for the
76
     *            {@link NamedArea#getIdInVocabulary() IdInVocabulary} of each
77
     *            area
78
     * @param wmsLayerName
79
     * @return the resulting table of the import, also together with diagnostic
80
     *         messages per NamedArea (id not found)
81
     * @throws IOException
82
     */
83
    public Map<NamedArea, String> readCsv(Reader reader, List<String> idSearchFields, String wmsLayerName) throws IOException {
84

    
85
        logger.setLevel(Level.DEBUG);
86

    
87
        Map<NamedArea, String> resultMap = new HashMap<>(areas.size());
88

    
89
        CSVReader csvReader = new CSVReader(reader, COMMA);
90

    
91
        // read header row and prepare the searchColumnMap
92
        String[] headerRow = csvReader.readNext();
93
        searchColumnMap = new HashMap<>();
94
        for(String colName : idSearchFields){
95
            int idx = ArrayUtils.indexOf(headerRow, colName);
96
            if(idx > -1){
97
                searchColumnMap.put(colName, idx);
98
            } else {
99
                logger.debug("no header row found for " + colName);
100
            }
101
        }
102

    
103
        // read the rest of the file
104
        List<String[]> data = csvReader.readAll();
105
        csvReader.close();
106
        csvReader = null; // release memory
107

    
108
        String matchIdCode;
109
        String matchColName;
110
        for(NamedArea a : areas){
111

    
112
            if(a.getIdInVocabulary() == null){
113
                String message = "has no IdInVocabulary";
114
                resultMap.put(a, message);
115
                logger.warn(a.getTitleCache() + " " + message);
116
                continue;
117
            }
118
            matchIdCode = null;
119
            matchColName = null;
120
            // search in each of the columns until found
121
            for(String colName : searchColumnMap.keySet()){
122

    
123
                int idx = searchColumnMap.get(colName);
124

    
125
                for(String[] row : data){
126
                    String fieldData = row[idx].trim();
127
                    if(a.getIdInVocabulary().equals(fieldData)){
128
                        // FOUND!
129
                        matchIdCode = fieldData;
130
                        break;
131
                    }
132
                }
133

    
134
                if(matchIdCode != null){
135
                    // no need to search in next column
136
                    matchColName = colName;
137
                    break;
138
                }
139

    
140
            } // END loop columns
141

    
142
            if(matchIdCode != null){
143
                //TODO need to clear the area mapping since the mapping impl can not distinguish multiple layers
144
                //     see http://dev.e-taxonomy.eu/trac/ticket/4263
145
                areaMapping.clear(a);
146

    
147
                GeoServiceArea geoServiceArea;
148
                geoServiceArea = areaMapping.valueOf(a);
149
                if(geoServiceArea == null){
150
                    geoServiceArea = new GeoServiceArea();
151
                }
152
                geoServiceArea.add(wmsLayerName, matchColName, matchIdCode);
153
                areaMapping.set(a, geoServiceArea );
154

    
155
                String message = matchColName + ": " + matchIdCode;
156
                resultMap.put(a, message);
157
                if(logger.isDebugEnabled()){
158
                    logger.debug(a.getIdInVocabulary() + ": " + message);
159
                }
160
            } else {
161
                String message = "no match for " + a.getIdInVocabulary();
162
                resultMap.put(a, message);
163
                logger.warn(message);
164
            }
165

    
166

    
167
        } // END of areas loop
168
        return resultMap;
169
    }
170

    
171
}
(14-14/14)