Package org.jboss.errai.demo.grocery.client.local

Source Code of org.jboss.errai.demo.grocery.client.local.StorePage

/**
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.errai.demo.grocery.client.local;

import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.persistence.EntityManager;

import org.gwtopenmaps.openlayers.client.*;
import org.gwtopenmaps.openlayers.client.control.ModifyFeature;
import org.gwtopenmaps.openlayers.client.control.ModifyFeatureOptions;
import org.gwtopenmaps.openlayers.client.control.OverviewMap;
import org.gwtopenmaps.openlayers.client.control.ScaleLine;
import org.gwtopenmaps.openlayers.client.event.MapMoveEndListener;
import org.gwtopenmaps.openlayers.client.feature.VectorFeature;
import org.gwtopenmaps.openlayers.client.geometry.LinearRing;
import org.gwtopenmaps.openlayers.client.geometry.Point;
import org.gwtopenmaps.openlayers.client.geometry.Polygon;
import org.gwtopenmaps.openlayers.client.layer.Markers;
import org.gwtopenmaps.openlayers.client.layer.OSM;
import org.gwtopenmaps.openlayers.client.layer.Vector;
import org.gwtopenmaps.openlayers.client.util.JSObject;
import org.jboss.errai.databinding.client.api.DataBinder;
import org.jboss.errai.databinding.client.api.InitialState;
import org.jboss.errai.databinding.client.api.PropertyChangeEvent;
import org.jboss.errai.databinding.client.api.PropertyChangeHandler;
import org.jboss.errai.demo.grocery.client.local.map.GoogleMapBootstrapper;
import org.jboss.errai.demo.grocery.client.local.map.LocationProvider;
import org.jboss.errai.demo.grocery.client.local.map.LocationProvider.LocationCallback;
import org.jboss.errai.demo.grocery.client.shared.Department;
import org.jboss.errai.demo.grocery.client.shared.Store;
import org.jboss.errai.ui.cordova.geofencing.GeoFencingProvider;
import org.jboss.errai.ui.cordova.geofencing.Region;
import org.jboss.errai.ui.nav.client.local.Page;
import org.jboss.errai.ui.nav.client.local.PageHidden;
import org.jboss.errai.ui.nav.client.local.PageShown;
import org.jboss.errai.ui.nav.client.local.PageState;
import org.jboss.errai.ui.nav.client.local.TransitionTo;
import org.jboss.errai.ui.shared.api.annotations.AutoBound;
import org.jboss.errai.ui.shared.api.annotations.Bound;
import org.jboss.errai.ui.shared.api.annotations.DataField;
import org.jboss.errai.ui.shared.api.annotations.EventHandler;
import org.jboss.errai.ui.shared.api.annotations.Templated;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.gen2.picker.client.SliderBar;
import com.google.gwt.maps.client.base.LatLng;
import com.google.gwt.maps.client.base.LatLngBounds;
import com.google.gwt.maps.client.events.place.PlaceChangeMapEvent;
import com.google.gwt.maps.client.events.place.PlaceChangeMapHandler;
import com.google.gwt.maps.client.placeslib.Autocomplete;
import com.google.gwt.maps.client.placeslib.AutocompleteOptions;
import com.google.gwt.maps.client.placeslib.AutocompleteType;
import com.google.gwt.maps.client.placeslib.PlaceGeometry;
import com.google.gwt.maps.client.placeslib.PlaceResult;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.TextBox;

@Dependent
@Templated("#main")
@Page
public class StorePage extends Composite {

    private static final Projection DEFAULT_PROJECTION = new Projection("EPSG:4326");
    public static final int DEFAULT_RADIUS = 100;

    @Inject
    private EntityManager em;

    @Inject
    private @DataField SimplePanel mapContainer;

    @Inject
    private @DataField Button saveButton;

    @Inject
    private @AutoBound DataBinder<Store> storeBinder;

    @Inject
    private @DataField TextBox locationSearchBox;

    @Inject
    private @Bound @DataField TextBox name;

    @Inject
    private @Bound @DataField TextBox address;

    @Inject
    private @Bound @DataField SliderBar radius;

    @Inject
    private @DataField SuggestBox addDepartment;

    @Inject
    private @DataField DepartmentList departmentList;

    @Inject
    private LocationProvider locationProvider;

    private @PageState("id") Long requestedStoreId;

    @Inject
    private TransitionTo<StoresPage> backToStoresPage;

    @Inject
    private GeoFencingProvider geoFencingProvider;

    private Marker marker;
    private Markers markers;
    private Vector vectorLayer;
    private ModifyFeature modifyControl;

    @PageShown
    private void setup() {

        // if a store was requested, retrieve it here (otherwise, we're editing a new, blank store instance)
        if (requestedStoreId != null) {
            Store found = em.find(Store.class, requestedStoreId);
            if (found == null) {
                Window.alert("No such store: " + requestedStoreId);
                backToStoresPage.go();
            }
            storeBinder.setModel(found, InitialState.FROM_MODEL);
        }

        departmentList.setItems(storeBinder.getModel().getDepartments());
        MultiWordSuggestOracle dso = (MultiWordSuggestOracle) addDepartment.getSuggestOracle();
        for (Department d : em.createNamedQuery("allDepartments", Department.class).getResultList()) {
            dso.add(d.getName());
        }
        addDepartment.getTextBox().addKeyPressHandler(new KeyPressHandler() {
            @Override
            public void onKeyPress(KeyPressEvent event) {
                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
                    if (addDepartment.getText().trim().length() == 0)
                        return;
                    Department department = Department.resolve(em, addDepartment.getText());
                    if (!storeBinder.getModel().getDepartments().contains(department)) {
                        storeBinder.getModel().getDepartments().add(department);
                        departmentList.setItems(storeBinder.getModel().getDepartments());
                    }
                    addDepartment.setText("");
                }
            }
        });

        GoogleMapBootstrapper.whenReady(new Runnable() {
            @Override
            public void run() {
                MapOptions defaultMapOptions = new MapOptions();
                defaultMapOptions.setNumZoomLevels(16);
                final MapWidget mapWidget = new MapWidget("100%", "100%", defaultMapOptions);
                mapContainer.add(mapWidget);
                final Map map = mapWidget.getMap();

                OSM osm = OSM.Mapnik("Mapnik");
                osm.setIsBaseLayer(true);
                map.addLayer(osm);
                vectorLayer = new Vector("Fence");
                map.addLayer(vectorLayer);
                markers = new Markers("Markers");
                map.addLayer(markers);
                map.addControl(new OverviewMap());
                map.addControl(new ScaleLine());

                ModifyFeatureOptions featureOptions = new ModifyFeatureOptions();
                featureOptions.setMode(ModifyFeature.RESIZE);
                featureOptions.onModificationEnd(new ModifyFeature.OnModificationEndListener() {
                    @Override
                    public void onModificationEnd(VectorFeature vectorFeature) {
                        float diameter = vectorFeature.getGeometry().getBounds().getWidth();
                        storeBinder.getModel().setRadius(diameter / 2);
                    }
                });

                storeBinder.addPropertyChangeHandler("radius", new PropertyChangeHandler<Double>() {
                    @Override
                    public void onPropertyChange(PropertyChangeEvent<Double> event) {
                        reDrawGeoFence(map);
                    }
                });

                modifyControl = new ModifyFeature(vectorLayer, featureOptions);
                map.addControl(modifyControl);

                placeMarkerAtStoreLocation(map);

                map.addMapMoveEndListener(new MapMoveEndListener() {

                    @Override
                    public void onMapMoveEnd(MapMoveEndEvent eventObject) {
                        Bounds extent = map.getExtent();
                        extent.transform(DEFAULT_PROJECTION, new Projection("EPSG:900913"));

                        // set up autocomplete search box for this place
                        AutocompleteType[] types = new AutocompleteType[2];
                        types[0] = AutocompleteType.ESTABLISHMENT;
                        types[1] = AutocompleteType.GEOCODE;

                        AutocompleteOptions options = AutocompleteOptions.newInstance();
                        options.setTypes(types);
                        LatLng sw = LatLng.newInstance(extent.getLowerLeftX(), extent.getLowerLeftY());
                        LatLng ne = LatLng.newInstance(extent.getUpperRightX(), extent.getUpperRightY());
                        options.setBounds(LatLngBounds.newInstance(sw, ne));

                        final Autocomplete autoComplete = Autocomplete.newInstance(locationSearchBox.getElement(), options);

                        autoComplete.addPlaceChangeHandler(new PlaceChangeMapHandler() {
                            @Override
                            public void onEvent(PlaceChangeMapEvent event) {
                                PlaceResult result = autoComplete.getPlace();
                                PlaceGeometry geometry = result.getGeometry();
                                LatLng center = geometry.getLocation();

                                Store store = storeBinder.getModel();
                                store.setName(result.getName());
                                store.setAddress(result.getFormatted_Address());
                                store.setLatitude(center.getLatitude());
                                store.setLongitude(center.getLongitude());
                                store.setRadius(DEFAULT_RADIUS);

                                placeMarkerAtStoreLocation(map);
                            }
                        });
                    }
                });
            }
        });
    }

    @PageHidden
    public void cleanup() {
        if (mapContainer.getWidget() != null) {
            mapContainer.getWidget().removeFromParent();
        }
    }

    @EventHandler("saveButton")
    private void save(ClickEvent e) {
        Store store = storeBinder.getModel();
        em.merge(store);
        em.flush();

        Region region = new Region((int) store.getId(), store.getLatitude(), store.getLongitude(), (int) store.getRadius());
        geoFencingProvider.addRegion(region);

        backToStoresPage.go();
    }

    /**
     * If the store's location is set to something reasonable (that is, not 0 degrees north, 0 degrees east), this method
     * centers the map on that location and places a marker on it. Otherwise, this method tries to center the map on the user's
     * current location.
     *
     * @param map the map to place the marker on
     */
    private void placeMarkerAtStoreLocation(final Map map) {
        // first remove old marker, if any
        if (marker != null) {
            markers.removeMarker(marker);
            marker = null;
        }

        LatLng center = getStoreLocation();
        if (center != null) {
            Size size = new Size(25, 22);
            Pixel pixel = new Pixel(-15, -11);
            Icon icon = new Icon("img/marker.png", size, pixel);
            marker = new Marker(convertPoint(map.getProjection(), center), icon);
            markers.addMarker(marker);

            centerMap(map, center, 15);
            reDrawGeoFence(map);
        }
        else {
            locationProvider.getCurrentPosition(new LocationCallback() {
                @Override
                public void onSuccess(LatLng result) {
                    centerMap(map, result, 13);
                }
            });
        }
    }

    private void reDrawGeoFence(Map map) {
        LonLat center = map.getCenter();
        center.transform(map.getProjection(), DEFAULT_PROJECTION.getProjectionCode());
        removeGeoFence();

        Point[] points = new Point[40];

        int angle = 0;
        for (int i = 0; i < 40; i++) {
            angle += 360 / 40;
            double radius = storeBinder.getModel().getRadius();
            LonLat lonLat = LonLat.narrowToLonLat(destinationVincenty(center.lon(), center.lat(), angle, radius));
            lonLat.transform("EPSG:4326", map.getProjection());
            points[i] = new Point(lonLat.lon(), lonLat.lat());
        }
        LinearRing ring = new LinearRing(points);
        Polygon polygon = new Polygon(new LinearRing[] { ring });

        vectorLayer.addFeature(new VectorFeature(polygon));
        modifyControl.activate();
    }

    private void removeGeoFence() {
        if (vectorLayer.getFeatures() != null) {
            for (VectorFeature vectorFeature : vectorLayer.getFeatures()) {
                vectorLayer.removeFeature(vectorFeature);
            }
        }
    }

    private native JSObject destinationVincenty(double lon, double lat, int angle, double distance) /*-{
        return $wnd.OpenLayers.Util.destinationVincenty(
                new $wnd.OpenLayers.LonLat(lon, lat), angle, distance);
    }-*/;

    private void centerMap(Map map, LatLng center, int zoomLevel) {
        LonLat lonlat = convertPoint(map.getProjection(), center);
        map.setCenter(lonlat, zoomLevel);
    }

    private LonLat convertPoint(String mapProjection, LatLng center) {
        LonLat lonlat = new LonLat(center.getLongitude(), center.getLatitude());
        lonlat.transform(DEFAULT_PROJECTION.getProjectionCode(), mapProjection);
        return lonlat;
    }

    /**
     * Returns the store's geolocation if it's been set, or null if the store location has not been set.
     */
    private LatLng getStoreLocation() {
        Store store = storeBinder.getModel();
        if (store.getLatitude() != 0.0 || store.getLongitude() != 0.0) {
            return LatLng.newInstance(store.getLatitude(), store.getLongitude());
        }
        else {
            return null;
        }
    }
}
TOP

Related Classes of org.jboss.errai.demo.grocery.client.local.StorePage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.