Как разместить маркеры на карте Google - PullRequest
26 голосов
/ 30 апреля 2011

Я использую инструмент карты Google из primefaces . Я хочу, чтобы мой пользователь мог разместить только один маркер на карте. Значения координат должны храниться в переменных управляемого компонента.

Как я могу это сделать? Посмотрите, что я сделал до сих пор:

Я создал карту:

    <f:view contentType="text/html">
            <p:gmap id="gmap" center="36.890257,30.707417" zoom="13" type="HYBRID"   
    style="width:600px;height:400px"  
    model="#{mapBean.emptyModel}"   
    onPointClick="handlePointClick(event);"   
    widgetVar="map" />  </f:view>

<p:dialog widgetVar="dlg" effect="FADE" effectDuration="0.5" close="false" fixedCenter="true">  
    <h:form prependId="false">  
        <h:panelGrid columns="2">  
            <h:outputLabel for="title" value="Title:" />  
            <p:inputText id="title" value="#{mapBean.title}" />  

            <f:facet name="footer">  
                <p:commandButton value="Add"   
                        actionListener="#{mapBean.addMarker}"   
                        update="messages"   
                        oncomplete="markerAddComplete()"/>  
                <p:commandButton value="Cancel" onclick="return cancel()"/>  
            </f:facet>  
        </h:panelGrid>  

        <h:inputHidden id="lat" value="#{newOfferSupportController.mapLocationX}" />  
        <h:inputHidden id="lng" value="#{newOfferSupportController.mapLocationY}" />  
    </h:form>  
</p:dialog>  

<script type="text/javascript">  
    var currentMarker = null;  

    function handlePointClick(event) {  
        if(currentMarker == null) {  
            document.getElementById('lat').value = event.latLng.lat();  
            document.getElementById('lng').value = event.latLng.lng();  

            currentMarker = new google.maps.Marker({  
                position:new google.maps.LatLng(event.latLng.lat(), event.latLng.lng())  
            });  

            map.addOverlay(currentMarker);  

            dlg.show();  
        }     
    }  

    function markerAddComplete() {  
        var title = document.getElementById('title');  
        currentMarker.setTitle(title.value);  
        title.value = "";  

        currentMarker = null;  
        dlg.hide();  
    }  

    function cancel() {  
        dlg.hide();  
        currentMarker.setMap(null);  
        currentMarker = null;  

        return false;  
    }  
</script>

Я также смазал переменные, которые будут содержать координаты:

@ManagedBean
@RequestScoped
public class NewOfferSupportController {

private float mapLocationX;
private float mapLocationY;

//Get & set methods

Все это работает так же, как и в простых страница , но у меня есть 2 проблемы:

Проблема 1: После того, как маркер установлен, его нельзя разместить снова.

Проблема 2: В той же форме, где находится карта, есть некоторые другие элементы, такие как текстовые поля. Я заметил, что проверка не происходит, когда я нажимаю на кнопку отправки, расположенную в форме, где находится карта. На самом деле форма вообще не отправляется (это не происходило до того, как я добавил карту), почему карта разрушается проверка? enter image description here

1 Ответ

6 голосов
/ 13 июня 2011

Проблема 1: После того, как маркер установлен, его нельзя разместить снова.

Эта проблема вызвана следующими причинами:

  1. Вы привязали широту и долготу к другому компоненту (NewOfferSupportController), чем к компоненту, который содержит модель карты (MapBean). Вы должны использовать пример MapBean в демонстрации PrimeFaces в качестве отправной точки дизайна для компонента NewOfferSupportController. Именно хранит набор маркеров. Скрытые входные данные должны указывать на этот компонент, поскольку в методе addMarker() эти значения будут добавлены. Из примера демонстрации просто переименуйте имя класса MapBean и переименуйте ссылки #{mapBean} в представлении на #{newOfferSupportController}.

  2. Ваш боб NewOfferSupportController является областью запроса, в то время как он должен быть виден.

    @ManagedBean
    @ViewScoped
    public class NewOfferSupportController implements Serializable {}
    

    Просмотр бобов в области видимости, пока вы взаимодействуете с одной и той же формой Ajax. Но компоненты bean-объекта запроса воссоздаются при каждом запросе (и, следовательно, также при каждом запросе Ajax!), Тем самым уничтожая маркеры, которые были помещены ранее на карте, и входные данные, которые вводятся перед добавлением маркеров.


Проблема 2: В той же форме, где находится карта, есть некоторые другие элементы, такие как текстовые поля. На самом деле форма не отправляется вообще (этого не было до того, как я добавил карту), почему карта нарушает проверку?

Это работает для меня. Это, вероятно, вызвано тем, что ваш NewOfferSupportController был помещен в область запроса вместо области просмотра.

Напомним, вот код, который я использовал в своем тесте:

вид:

<p:growl id="messages" showDetail="true" />  

<h:form>
    <p:gmap id="gmap" center="36.890257,30.707417" zoom="13" type="HYBRID" style="width:600px;height:400px"  
        model="#{mapBean.mapModel}" onPointClick="handlePointClick(event);" widgetVar="map" />
    <h:inputText value="#{mapBean.input}" required="true" />
    <p:commandButton value="submit" action="#{mapBean.submit}" update="messages" />
</h:form>

<p:dialog widgetVar="dlg" effect="FADE" effectDuration="0.5" close="false" fixedCenter="true">  
    <h:form prependId="false">  
        <h:panelGrid columns="2">  
            <h:outputLabel for="title" value="Title:" />  
            <p:inputText id="title" value="#{mapBean.title}" />  

            <f:facet name="footer">  
                <p:commandButton value="Add" actionListener="#{mapBean.addMarker}"   
                    update="messages" oncomplete="markerAddComplete()"/>  
                <p:commandButton value="Cancel" onclick="return cancel()"/>  
            </f:facet>
        </h:panelGrid>

        <h:inputHidden id="lat" value="#{mapBean.lat}" />  
        <h:inputHidden id="lng" value="#{mapBean.lng}" />
    </h:form>  
</p:dialog>  

(я не изменил код <script> в примере с витриной, просто добавил его без изменений)

Bean:

@ManagedBean
@ViewScoped
public class MapBean implements Serializable {  

    private MapModel mapModel;  
    private String title;  
    private double lat;  
    private double lng;  
    private String input;

    public MapBean() {  
        mapModel = new DefaultMapModel();  
    }  

    public void addMarker(ActionEvent actionEvent) {  
        mapModel.addOverlay(new Marker(new LatLng(lat, lng), title));  
        addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Added", "Lat:" + lat + ", Lng:" + lng));  
    }  

    public void submit() {
        addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Form submitted", "Amount markers: " + mapModel.getMarkers().size() + ", Input: " + input));
    }

    public void addMessage(FacesMessage message) {  
        FacesContext.getCurrentInstance().addMessage(null, message);  
    }  

    // Getters+setters.
}
...