Project

General

Profile

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

    
12
import java.awt.Color;
13
import java.io.IOException;
14
import java.io.Reader;
15
import java.util.ArrayList;
16
import java.util.Collection;
17
import java.util.EnumSet;
18
import java.util.HashSet;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.UUID;
23

    
24
import javax.persistence.EntityNotFoundException;
25

    
26
import org.apache.log4j.Logger;
27
import org.springframework.beans.factory.annotation.Autowired;
28
import org.springframework.stereotype.Service;
29
import org.springframework.transaction.annotation.Transactional;
30

    
31
import eu.etaxonomy.cdm.api.service.IDescriptionService;
32
import eu.etaxonomy.cdm.api.service.dto.DistributionInfoDTO;
33
import eu.etaxonomy.cdm.api.service.dto.DistributionInfoDTO.InfoPart;
34
import eu.etaxonomy.cdm.api.utility.DescriptionUtility;
35
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
36
import eu.etaxonomy.cdm.model.common.Language;
37
import eu.etaxonomy.cdm.model.common.MarkerType;
38
import eu.etaxonomy.cdm.model.common.TermVocabulary;
39
import eu.etaxonomy.cdm.model.description.Distribution;
40
import eu.etaxonomy.cdm.model.description.Feature;
41
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
42
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
43
import eu.etaxonomy.cdm.model.description.TaxonDescription;
44
import eu.etaxonomy.cdm.model.location.NamedArea;
45
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
46
import eu.etaxonomy.cdm.model.location.Point;
47
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
48
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
49
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
50
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
51
import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
52
import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
53
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
54
import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;
55

    
56
/**
57
 * @author a.kohlbecker
58
 * @date 18.06.2009
59
 *
60
 */
61
@Service
62
@Transactional(readOnly = true)
63
public class EditGeoService implements IEditGeoService {
64
    public static final Logger logger = Logger.getLogger(EditGeoService.class);
65

    
66
    @Autowired
67
    private IDescriptionDao dao;
68

    
69
    @Autowired
70
    private IGeoServiceAreaMapping areaMapping;
71

    
72
    @Autowired
73
    private IDescriptionService descriptionService;
74

    
75
    @Autowired
76
    private ITermVocabularyDao vocabDao;
77

    
78
    private IDefinedTermDao termDao;
79
    @Autowired
80
    public void setTermDao(IDefinedTermDao termDao) {
81
        this.termDao = termDao;
82
        EditGeoServiceUtilities.setTermDao(termDao);
83
    }
84

    
85
    @Autowired
86
    private IOccurrenceDao occurrenceDao;
87

    
88
    private Set<Feature> getDistributionFeatures() {
89
        Set<Feature> distributionFeature = new HashSet<Feature>();
90
        Feature feature = (Feature) termDao.findByUuid(Feature.DISTRIBUTION().getUuid());
91
        distributionFeature.add(feature);
92
        return distributionFeature;
93
    }
94

    
95
    /**
96
     * {@inheritDoc}
97
     */
98
    @Override
99
    public String getDistributionServiceRequestParameterString(List<TaxonDescription> taxonDescriptions,
100
            boolean subAreaPreference,
101
            boolean statusOrderPreference,
102
            Set<MarkerType> hideMarkedAreas, Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors,
103
            List<Language> langs) {
104

    
105
        Set<Distribution> distributions = new HashSet<Distribution>();
106
        for (TaxonDescription taxonDescription : taxonDescriptions) {
107
            List<Distribution> result = (List) dao.getDescriptionElements(
108
                    taxonDescription,
109
                    null,
110
                    getDistributionFeatures(),
111
                    Distribution.class,
112
                    null,
113
                    null,
114
                    null);
115
            distributions.addAll(result);
116
        }
117

    
118
        String uriParams = getDistributionServiceRequestParameterString(distributions,
119
                subAreaPreference,
120
                statusOrderPreference,
121
                hideMarkedAreas,
122
                presenceAbsenceTermColors,
123
                langs);
124

    
125
        return uriParams;
126
    }
127

    
128

    
129

    
130
    /**
131
     * {@inheritDoc}
132
     */
133
    @Override
134
    public String getDistributionServiceRequestParameterString(
135
            Set<Distribution> distributions,
136
            boolean subAreaPreference,
137
            boolean statusOrderPreference,
138
            Set<MarkerType> hideMarkedAreas,
139
            Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors,
140
            List<Language> langs) {
141

    
142
        Collection<Distribution> filteredDistributions = DescriptionUtility.filterDistributions(distributions, subAreaPreference, statusOrderPreference, hideMarkedAreas);
143

    
144

    
145
        String uriParams = EditGeoServiceUtilities.getDistributionServiceRequestParameterString(filteredDistributions,
146
                hideMarkedAreas,
147
                areaMapping,
148
                presenceAbsenceTermColors,
149
                null, langs);
150
        return uriParams;
151
    }
152

    
153
    @Override
154
    @Deprecated
155
    public String getDistributionServiceRequestParameterString(TaxonDescription taxonDescription,
156
            boolean subAreaPreference,
157
            boolean statusOrderPreference,
158
            Set<MarkerType> hideMarkedAreas,
159
            Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors,
160
            List<Language> langs) {
161

    
162
        List<TaxonDescription> taxonDescriptions = new ArrayList<TaxonDescription>();
163
        taxonDescriptions.add(taxonDescription);
164

    
165
        return getDistributionServiceRequestParameterString(taxonDescriptions,
166
                subAreaPreference,
167
                statusOrderPreference,
168
                hideMarkedAreas, presenceAbsenceTermColors,
169
                langs);
170
    }
171

    
172
    /**
173
     * {@inheritDoc}
174
     */
175
    @Override
176
    public OccurrenceServiceRequestParameterDto getOccurrenceServiceRequestParameterString(List<SpecimenOrObservationBase> specimensOrObersvations,
177
            Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors) {
178

    
179
        List<Point> fieldUnitPoints = new ArrayList<Point>();
180
        List<Point> derivedUnitPoints = new ArrayList<Point>();
181

    
182
        IndividualsAssociation individualsAssociation;
183
        DerivedUnit derivedUnit;
184

    
185
        for (SpecimenOrObservationBase specimenOrObservationBase : specimensOrObersvations) {
186
            SpecimenOrObservationBase<?> specimenOrObservation = occurrenceDao
187
                    .load(specimenOrObservationBase.getUuid());
188

    
189
            if (specimenOrObservation instanceof FieldUnit) {
190
                fieldUnitPoints.add(((FieldUnit) specimenOrObservation).getGatheringEvent()
191
                        .getExactLocation());
192
            }
193
            if (specimenOrObservation instanceof DerivedUnit) {
194
                registerDerivedUnitLocations((DerivedUnit) specimenOrObservation, derivedUnitPoints);
195
            }
196
        }
197

    
198
        return EditGeoServiceUtilities.getOccurrenceServiceRequestParameterString(fieldUnitPoints,
199
                derivedUnitPoints, specimenOrObservationTypeColors);
200

    
201
    }
202

    
203
    public String getCondensedDistributionString(List<TaxonDescription> taxonDescriptions,
204
            boolean subAreaPreference,
205
            boolean statusOrderPreference,
206
            Set<MarkerType> hideMarkedAreas,
207
            CondensedDistributionStringRecipe recipe,
208
            List<Language> langs) {
209
        return null;
210
    }
211

    
212
    /**
213
     * @param derivedUnit
214
     * @param derivedUnitPoints
215
     */
216
    private void registerDerivedUnitLocations(DerivedUnit derivedUnit, List<Point> derivedUnitPoints) {
217

    
218
        Set<SpecimenOrObservationBase> originals = derivedUnit.getOriginals();
219
        if (originals != null) {
220
            for (SpecimenOrObservationBase original : originals) {
221
                if (original instanceof FieldUnit) {
222
                    if (((FieldUnit) original).getGatheringEvent() != null) {
223
                        Point point = ((FieldUnit) original).getGatheringEvent().getExactLocation();
224
                        if (point != null) {
225
                            // points with no longitude or latitude should not exist
226
                            // see  #4173 ([Rule] Longitude and Latitude in Point must not be null)
227
                            if (point.getLatitude() == null || point.getLongitude() == null){
228
                                continue;
229
                            }
230
                            // FIXME: remove next statement after
231
                            // DerivedUnitFacade or ABCD import is fixed
232
                            //
233
                            if(point.getLatitude() == 0.0 || point.getLongitude() == 0.0) {
234
                                continue;
235
                            }
236
                            derivedUnitPoints.add(point);
237
                        }
238
                    }
239
                } else {
240
                    registerDerivedUnitLocations((DerivedUnit) original, derivedUnitPoints);
241
                }
242
            }
243
        }
244

    
245
    }
246

    
247

    
248
    /**
249
     * {@inheritDoc}
250
     */
251
    @Override
252
    public void setMapping(NamedArea area, GeoServiceArea geoServiceArea) {
253
        areaMapping.set(area, geoServiceArea);
254

    
255
    }
256

    
257
    /**
258
     * {@inheritDoc}
259
     */
260
    @Override
261
    @Transactional(readOnly=false)
262
    public Map<NamedArea, String> mapShapeFileToNamedAreas(Reader csvReader,
263
            List<String> idSearchFields, String wmsLayerName, UUID areaVocabularyUuid,
264
            Set<UUID> namedAreaUuids) throws IOException {
265

    
266
        Set<NamedArea> areas = new HashSet<NamedArea>();
267

    
268
        if(areaVocabularyUuid != null){
269
            TermVocabulary<NamedArea> areaVocabulary = vocabDao.load(areaVocabularyUuid);
270
            if(areaVocabulary == null){
271
                throw new EntityNotFoundException("No Vocabulary found for uuid " + areaVocabularyUuid);
272
            }
273
            areas.addAll(areaVocabulary.getTerms());
274
        }
275
        if(namedAreaUuids != null && !namedAreaUuids.isEmpty()){
276
            for(DefinedTermBase dtb : termDao.list(namedAreaUuids, null, null, null, null)){
277
                areas.add((NamedArea)dtb);
278
            }
279
        }
280

    
281
        ShpAttributesToNamedAreaMapper mapper = new ShpAttributesToNamedAreaMapper(areas, areaMapping);
282
        Map<NamedArea, String> resultMap = mapper.readCsv(csvReader, idSearchFields, wmsLayerName);
283
        termDao.saveOrUpdateAll((Collection)areas);
284
        return resultMap;
285
    }
286

    
287

    
288
    @Override
289
    public DistributionInfoDTO composeDistributionInfoFor(EnumSet<DistributionInfoDTO.InfoPart> parts, UUID taxonUUID,
290
            boolean subAreaPreference, boolean statusOrderPreference, Set<MarkerType> hideMarkedAreas,
291
            Set<NamedAreaLevel> omitLevels, Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors,
292
            List<Language> languages,  List<String> propertyPaths){
293

    
294
        DistributionInfoDTO dto = new DistributionInfoDTO();
295

    
296
        // Adding default initStrategies to improve the performance of this method
297
        // adding 'status' and 'area' has a good positive effect:
298
        // filterDistributions() only takes 21% of the total method time (before it was 46%)
299
        // at the same time the cost of the getDescriptionElementForTaxon is not increased at all!
300
        //
301
        // adding 'markers.markerType' is not improving the performance since it only
302
        // moved the load from the filter method to the getDescriptionElementForTaxon()
303
        // method.
304
        // overall improvement by this means is by 42% (from 77,711 ms to 44,868 ms)
305
        ArrayList<String> initStrategy = new ArrayList<String>(propertyPaths);
306
        if(!initStrategy.contains("status")) {
307
            initStrategy.add("status");
308
        }
309
        if(!initStrategy.contains("area")) {
310
            initStrategy.add("area");
311
        }
312
        if(!initStrategy.contains("markers.markerType")) {
313
            initStrategy.add("markers.markerType");
314
        }
315

    
316
        List<Distribution> distributions = dao.getDescriptionElementForTaxon(taxonUUID, null, Distribution.class, null, null, initStrategy);
317
        Set<Distribution> filteredDistributions = DescriptionUtility.filterDistributions(distributions, subAreaPreference, statusOrderPreference, hideMarkedAreas);
318

    
319
        if(parts.contains(InfoPart.elements)) {
320
            dto.setElements(filteredDistributions);
321
        }
322

    
323
        if(parts.contains(InfoPart.tree)) {
324
            dto.setTree(DescriptionUtility.orderDistributions(termDao, omitLevels, filteredDistributions));
325
        }
326

    
327
        if (parts.contains(InfoPart.mapUriParams)) {
328
            dto.setMapUriParams(EditGeoServiceUtilities.getDistributionServiceRequestParameterString(filteredDistributions,
329
                    hideMarkedAreas,
330
                    areaMapping,
331
                    presenceAbsenceTermColors,
332
                    null, languages));
333
        }
334

    
335
        if(parts.contains(InfoPart.condensedStatusString)) {
336
            logger.error("condensedStatusString not yet supported:  #3907 (EuroMed: implement condensed status string of distribution information)");
337
        }
338

    
339
        return dto;
340
    }
341
}
(1-1/8)