Project

General

Profile

Download (7.69 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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.vaadin.component.common;
10

    
11
import org.apache.commons.lang3.StringUtils;
12
import org.apache.log4j.Logger;
13
import org.vaadin.addon.leaflet.LCircle;
14
import org.vaadin.addon.leaflet.LMap;
15
import org.vaadin.addon.leaflet.LMarker;
16
import org.vaadin.addon.leaflet.LTileLayer;
17
import org.vaadin.addon.leaflet.LeafletClickEvent;
18

    
19
import com.vaadin.data.fieldgroup.BeanFieldGroup;
20
import com.vaadin.data.fieldgroup.FieldGroup;
21
import com.vaadin.data.util.BeanItem;
22
import com.vaadin.ui.Component;
23
import com.vaadin.ui.CssLayout;
24
import com.vaadin.ui.GridLayout;
25
import com.vaadin.ui.Label;
26
import com.vaadin.ui.ListSelect;
27
import com.vaadin.ui.TextField;
28

    
29
import eu.etaxonomy.cdm.model.location.Point;
30
import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
31
import eu.etaxonomy.cdm.vaadin.util.converter.GeoLocationConverterValidator;
32
import eu.etaxonomy.cdm.vaadin.util.converter.GeoLocationConverterValidator.Axis;
33
import eu.etaxonomy.cdm.vaadin.util.converter.IntegerConverter;
34
import eu.etaxonomy.vaadin.component.CompositeCustomField;
35

    
36
/**
37
 * @author a.kohlbecker
38
 * @since Jun 22, 2017
39
 *
40
 */
41
public class GeoLocationField extends CompositeCustomField<Point> {
42

    
43
    private static final Logger logger = Logger.getLogger(GeoLocationField.class);
44

    
45
    private static final long serialVersionUID = 1122123034547920390L;
46

    
47
    private static final String PRIMARY_STYLE = "v-geolocation-field";
48

    
49
    private BeanFieldGroup<Point> fieldGroup = new BeanFieldGroup<>(Point.class);
50

    
51
    private TextField longitudeField = new TextFieldNFix("Longitude");
52
    private TextField latitudeField = new TextFieldNFix("Latitude");
53
    private Label longLatParsed = new Label();
54
    private TextField errorRadiusField = new TextFieldNFix("Error radius (m)");
55
    private ListSelect referenceSystemSelect;
56

    
57
    private LMap map = new LMap();
58
    private LMarker mapMarker = new LMarker();
59
    private LCircle errorRadiusMarker = null;
60

    
61
    private CssLayout mapWrapper;
62

    
63

    
64
    /**
65
     *
66
     */
67
    public GeoLocationField() {
68
        super();
69
    }
70

    
71
    public GeoLocationField(String caption) {
72
        super();
73
        setCaption(caption);
74
    }
75

    
76
    /**
77
     * {@inheritDoc}
78
     */
79
    @Override
80
    protected Component initContent() {
81
        super.setPrimaryStyleName(PRIMARY_STYLE);
82

    
83
        errorRadiusField.setConverter(new IntegerConverter());
84

    
85

    
86
        map = new LMap();
87
        // LTileLayer baseLayer = new LOpenStreetMapLayer();
88
        LTileLayer baseLayer = new LTileLayer("https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png");
89
        baseLayer.setAttributionString("Map data © <a href=\"https://openstreetmap.org/copyright\">OpenStreetMap</a>-contributors, SRTM | Map style: © <a href=\"http://opentopomap.org\">OpenTopoMap</a> (<a href=\"https://creativecommons.org/licenses/by-sa/3.0/\">CC-BY-SA</a>)");
90
        map.addBaseLayer(baseLayer, null);
91
        map.setDraggingEnabled(true);
92
        map.setScrollWheelZoomEnabled(false);
93
        map.removeControl(map.getLayersControl());
94
        map.addClickListener(e -> refreshMap(e));
95
        // map.getZoomControl().addListener(ClickEvent.class, target, method);
96

    
97
        mapWrapper = new CssLayout(longLatParsed, map);
98
        mapWrapper.setSizeFull();
99
        mapWrapper.setStyleName("map-wrapper");
100
        longLatParsed.setWidthUndefined();
101

    
102
        longitudeField.setConverter(new GeoLocationConverterValidator(Axis.LONGITUDE));
103
        longitudeField.addValidator(new GeoLocationConverterValidator(Axis.LONGITUDE));
104
        longitudeField.setBuffered(false);
105
        longitudeField.addValueChangeListener(e -> updateMap());
106

    
107
        latitudeField.setConverter(new GeoLocationConverterValidator(Axis.LATITUDE));
108
        latitudeField.addValidator(new GeoLocationConverterValidator(Axis.LATITUDE));
109
        latitudeField.setBuffered(false);
110
        latitudeField.addValueChangeListener(e -> updateMap());
111

    
112
        errorRadiusField.addValueChangeListener( e -> updateMap());
113

    
114
        referenceSystemSelect = new ListSelect("Reference system");
115
        referenceSystemSelect.setNullSelectionAllowed(false);
116
        referenceSystemSelect.setRows(1);
117
        referenceSystemSelect.setWidth(100, Unit.PERCENTAGE);
118

    
119
        GridLayout root = new GridLayout();
120
        root.setRows(2);
121
        root.setColumns(3);
122
        root.setStyleName("wrapper");
123
        root.addComponent(latitudeField, 0, 0);
124
        root.addComponent(longitudeField, 1, 0);
125
        root.addComponent(errorRadiusField, 0, 1);
126
        root.addComponent(referenceSystemSelect, 1, 1);
127
        // root.addComponent(map, 2, 1);
128
        root.addComponent(mapWrapper, 2, 0, 2, 1);
129
        root.setColumnExpandRatio(2, 1.0f);
130
        root.setRowExpandRatio(1, 1.0f);
131

    
132
        addStyledComponents(longitudeField, latitudeField, errorRadiusField, referenceSystemSelect, longLatParsed);
133
        addSizedComponent(root);
134

    
135
        fieldGroup.bind(longitudeField, "longitude");
136
        fieldGroup.bind(latitudeField, "latitude");
137
        fieldGroup.bind(errorRadiusField, "errorRadius");
138
        fieldGroup.bind(referenceSystemSelect, "referenceSystem");
139

    
140
        return root;
141
    }
142

    
143
    /**
144
     *
145
     */
146
    protected void updateMap() {
147
        // using the string representations for UI display
148
        longLatParsed.setValue(longitudeField.getValue() + "/" + latitudeField.getValue());
149
        map.removeComponent(mapMarker);
150
        if(errorRadiusMarker != null){
151
            map.removeComponent(errorRadiusMarker);
152
        }
153
        Double longitude = (Double) longitudeField.getConverter().convertToModel(longitudeField.getValue(), Double.class, null);
154
        Double latitude = (Double) latitudeField.getConverter().convertToModel(latitudeField.getValue(), Double.class, null);
155
        logger.debug("panning map to " + longitude + "/" + latitude);
156
        if(longitude != null && latitude != null){
157
            map.setZoomLevel(10);
158
            if(!StringUtils.isEmpty(errorRadiusField.getValue())){
159
                try{
160
                    double errorRadius = Double.parseDouble(errorRadiusField.getValue());
161
                    if(errorRadius > 0){
162
                        errorRadiusMarker = new LCircle(latitude, longitude, errorRadius);
163
                        errorRadiusMarker.setColor("#ff0000");
164
                        errorRadiusMarker.setWeight(1);
165
                        map.addComponents(errorRadiusMarker);
166
                    }
167
                } catch(Exception e){ /* IGNORE */ }
168
            }
169
            mapMarker.setPoint(new org.vaadin.addon.leaflet.shared.Point(latitude, longitude));
170
            map.addComponents(mapMarker);
171
            map.setCenter(latitude, longitude);
172
        } else {
173
            map.setZoomLevel(1);
174
            map.setCenter(40, 0);
175
        }
176
    }
177

    
178
    protected void refreshMap(LeafletClickEvent e) {
179
        logger.debug("map click");
180
    }
181

    
182
    /**
183
     * {@inheritDoc}
184
     */
185
    @Override
186
    public Class<? extends Point> getType() {
187
        return Point.class;
188
    }
189

    
190
    @Override
191
    protected void setInternalValue(Point newValue) {
192
        if(newValue == null){
193
            newValue = Point.NewInstance();
194
        }
195
        super.setInternalValue(newValue);
196
        fieldGroup.setItemDataSource(new BeanItem<Point>(newValue));
197
        updateMap();
198
    }
199

    
200
    /**
201
     * {@inheritDoc}
202
     */
203
    @Override
204
    protected void addDefaultStyles() {
205
        // no default styles so far
206

    
207
    }
208

    
209
    /**
210
     * {@inheritDoc}
211
     */
212
    @Override
213
    public FieldGroup getFieldGroup() {
214
        return fieldGroup;
215
    }
216

    
217
    public ListSelect getReferenceSystemSelect() {
218
        return referenceSystemSelect;
219
    }
220

    
221

    
222

    
223
}
(3-3/8)