緯度と経度から地図を表示する仕組みを作り始めた。
@@ -75,9 +75,8 @@ | ||
75 | 75 | <div> |
76 | 76 | <span wicket:id="rawDate">9999</span> |
77 | 77 | </div> |
78 | - <div wicket:id="rawDataView"> | |
79 | - | |
80 | - </div> | |
78 | + <div wicket:id="rawDataView"/> | |
79 | + <div wicket:id="locationViewer"/> | |
81 | 80 | <p> |
82 | 81 | <div wicket:id="workTimeEdit"> |
83 | 82 | <label>訂正フォーム</label> |
@@ -33,6 +33,7 @@ | ||
33 | 33 | import org.clearfy.ClearfyRoles; |
34 | 34 | import org.clearfy.ClearfySection; |
35 | 35 | import org.clearfy.components.MonthPicker; |
36 | +import org.clearfy.components.gapi.LocationViewer; | |
36 | 37 | import org.clearfy.components.tableview.DataTableView; |
37 | 38 | import org.clearfy.components.tableview.Record; |
38 | 39 | import org.clearfy.components.tableview.ResultSetProvider; |
@@ -67,6 +68,8 @@ | ||
67 | 68 | |
68 | 69 | private WorkTimeEdit workTimeEdit; |
69 | 70 | |
71 | + private LocationViewer locationViewer; | |
72 | + | |
70 | 73 | public TimeCardEmployeeRecordView(String id, ClearfyPage page) { |
71 | 74 | super(id, page); |
72 | 75 | } |
@@ -81,6 +84,7 @@ | ||
81 | 84 | monthPicker = new MonthPicker("monthPicker", this.page) { |
82 | 85 | @Override |
83 | 86 | public void onYearMonthChanged(AjaxRequestTarget target) { |
87 | + | |
84 | 88 | workingReportView.setYear(this.getYear()); |
85 | 89 | workingReportView.setMonth(this.getMonth()); |
86 | 90 | workingReportView.drawWorkingReport(); |
@@ -104,7 +108,7 @@ | ||
104 | 108 | |
105 | 109 | @Override |
106 | 110 | public void onEmployeeSelected(AjaxRequestTarget target, |
107 | - Record record) { | |
111 | + Record record) { | |
108 | 112 | |
109 | 113 | int employeeId = this.getSelectedEmployeeId(); |
110 | 114 |
@@ -209,7 +213,7 @@ | ||
209 | 213 | ) { |
210 | 214 | @Override |
211 | 215 | public void onSelected(AjaxRequestTarget target, |
212 | - Record selected) { | |
216 | + Record selected) { | |
213 | 217 | onRecordSelected(target, selected); |
214 | 218 | } |
215 | 219 | }; |
@@ -235,6 +239,9 @@ | ||
235 | 239 | this.rawDataView.setOutputMarkupId(true); |
236 | 240 | this.add(this.rawDataView); |
237 | 241 | |
242 | + this.locationViewer = new LocationViewer("locationViewer", this.page); | |
243 | + this.add(this.locationViewer); | |
244 | + | |
238 | 245 | this.workTimeSummary = new WorkTimeSummary("workTimeSummary", this.page); |
239 | 246 | this.workTimeSummary.setOutputMarkupId(true); |
240 | 247 | this.add(this.workTimeSummary); |
@@ -241,13 +248,17 @@ | ||
241 | 248 | |
242 | 249 | //権限レベルがUserのときは、個人を固定して表示する. |
243 | 250 | this.employeeSelecter.setLocked(false); |
244 | - if (this.getCurrentRoles().hasRole(ClearfyRoles.USER) | |
245 | - || this.getCurrentRoles().hasRole(ClearfyRoles.MANAGEMENT_USER)) { | |
251 | + if (this.getCurrentRoles() | |
252 | + .hasRole(ClearfyRoles.USER) | |
253 | + || this.getCurrentRoles() | |
254 | + .hasRole(ClearfyRoles.MANAGEMENT_USER)) { | |
246 | 255 | |
247 | - String userId = this.getCurrentSession().getUserId(); | |
256 | + String userId = this.getCurrentSession() | |
257 | + .getUserId(); | |
248 | 258 | String empId = this.employeeSelecter.getEmployeeIdByUserId(userId); |
249 | 259 | |
250 | - if (this.getCurrentRoles().hasRole(ClearfyRoles.USER)) { | |
260 | + if (this.getCurrentRoles() | |
261 | + .hasRole(ClearfyRoles.USER)) { | |
251 | 262 | this.employeeSelecter.setLocked(true); |
252 | 263 | } |
253 | 264 |
@@ -37,119 +37,11 @@ | ||
37 | 37 | <div class="section center half left" > |
38 | 38 | <h3>打刻</h3> |
39 | 39 | <form wicket:id="timeRecorder"> |
40 | - | |
41 | 40 | <div> |
42 | 41 | <span wicket:id="clock" class="timecard main clock"/> |
43 | 42 | <input type="button" value="打刻" class="timecard main button" wicket:id="timeRecordButton"/> |
44 | 43 | </div> |
45 | - <div class="locationpicker" > | |
46 | - <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCY2EpuxW8aKPvtDVWt9wmqBPKRHRoPwTQ&callback=initMap" | |
47 | - async defer> | |
48 | - </script> | |
49 | - <label class="localtionpicker title">現在位置</label> | |
50 | - <div class="localtionpicker map" name="map" style=""></div> | |
51 | - <div class="localtionpicker coordinates" name="localtionpicker.coordinates"> | |
52 | - <div> | |
53 | - <label class="locatitonpicker coordinates label">緯度</label> | |
54 | - <input type="text" class="locationpicker corrdinaltes parameter" name="latitude" wicket:id="latitude" value="緯度" /> | |
55 | - </div> | |
56 | - <div> | |
57 | - <label class="locatitonpicker coordinates label">経度</label> | |
58 | - <input type="text" class="locationpicker corrdinaltes parameter" name="longitude" wicket:id="longitude" value="経度"/> | |
59 | - </div> | |
60 | - <div> | |
61 | - <label class="locatitonpicker coordinates label">誤差</label> | |
62 | - <input type="text" class="locationpicker corrdinaltes parameter" name="accuracy" wicket:id="accuracy" value="誤差" /> | |
63 | - </div> | |
64 | - </div> | |
65 | - <input class="localtionpicker result" type="hidden" name="map_result" /> | |
66 | - <div class="localtionpicker message" name="show_result" /> | |
67 | - <script> | |
68 | - var currentPosition; | |
69 | - var map; | |
70 | - var marker; | |
71 | - function initMap() { | |
72 | - //ユーザーの現在の位置情報を取得 | |
73 | - navigator.geolocation.getCurrentPosition(successCallback, errorCallback); | |
74 | - } | |
75 | - | |
76 | - /***** ユーザーの現在の位置情報を取得 *****/ | |
77 | - function successCallback(position) { | |
78 | - currentPosition = position; | |
79 | - //wicketとの干渉を避けるため、getElementsByNameで操作 | |
80 | - document.getElementsByName('latitude')[0].value = | |
81 | - position.coords.latitude; | |
82 | - document.getElementsByName('longitude')[0].value = | |
83 | - position.coords.longitude; | |
84 | - document.getElementsByName('accuracy')[0].value = | |
85 | - position.coords.accuracy; | |
86 | - | |
87 | - var position = new google.maps.LatLng( | |
88 | - currentPosition.coords.latitude, | |
89 | - currentPosition.coords.longitude); | |
90 | - | |
91 | - var accuracy = currentPosition.coords.accuracy; | |
92 | - | |
93 | - var mapOptions = { | |
94 | - center: position, | |
95 | - zoom: 18, | |
96 | - mapTypeId: google.maps.MapTypeId.ROADMAP | |
97 | - }; | |
98 | - map = new google.maps.Map(document.getElementsByName('map')[0], mapOptions); | |
99 | - var markerOptions = { | |
100 | - position: position, | |
101 | - map: map | |
102 | - }; | |
103 | - marker = new google.maps.Marker(markerOptions); | |
104 | - document.getElementsByName('map_result')[0].setAttribute("value", 0); | |
105 | - | |
106 | - var circleOptions = { | |
107 | - center: position, // 中心点(google.maps.LatLng) | |
108 | - fillColor: '#00AA00', // 塗りつぶし色 | |
109 | - fillOpacity: 0.1, // 塗りつぶし透過度(0: 透明 ⇔ 1:不透明) | |
110 | - map: map, // 表示させる地図(google.maps.Map) | |
111 | - radius: accuracy, // 半径(m) | |
112 | - strokeColor: '#008800', // 外周色 | |
113 | - strokeOpacity: 1, // 外周透過度(0: 透明 ⇔ 1:不透明) | |
114 | - strokeWeight: 1 // 外周太さ(ピクセル) | |
115 | - }; | |
116 | - | |
117 | - new google.maps.Circle(circleOptions); | |
118 | - | |
119 | - var wcall = wicketAjaxGet('$url$' + '$args$', | |
120 | - function () { | |
121 | - document.write("SUCCESS"); | |
122 | - }, | |
123 | - function () { | |
124 | - document.write("ERROR"); | |
125 | - } | |
126 | - ); | |
127 | - | |
128 | - } | |
129 | - | |
130 | - /***** 位置情報が取得できない場合 *****/ | |
131 | - function errorCallback(error) { | |
132 | - var err_msg = ""; | |
133 | - switch (error.code) | |
134 | - { | |
135 | - case 1: | |
136 | - err_msg = "位置情報の利用が許可されていません.<br>許可をすると当ページで打刻ができるようになります."; | |
137 | - break; | |
138 | - case 2: | |
139 | - err_msg = "デバイスの位置が判定できません"; | |
140 | - break; | |
141 | - case 3: | |
142 | - err_msg = "タイムアウトしました"; | |
143 | - break; | |
144 | - } | |
145 | - document.getElementsByName('map')[0].setAttribute("style", "display: none;"); | |
146 | - document.getElementsByName('localtionpicker.coordinates')[0].setAttribute("style", "display: none;"); | |
147 | - document.getElementsByName('map_result')[0].setAttribute("value", error.code); | |
148 | - document.getElementsByName("show_result")[0].innerHTML = err_msg; | |
149 | - //デバッグ用→ document.getElementById("show_result").innerHTML = error.message; | |
150 | - } | |
151 | - </script> | |
152 | - </div> | |
44 | + <div class="locationpicker" wicket:id="currentLocationPicker" /> | |
153 | 45 | </form> |
154 | 46 | </div> |
155 | 47 | <div class="section center"> |
@@ -23,10 +23,16 @@ | ||
23 | 23 | */ |
24 | 24 | package org.clearfy.plugin.timecard; |
25 | 25 | |
26 | +import java.math.BigDecimal; | |
27 | +import java.sql.ResultSet; | |
28 | +import java.sql.SQLException; | |
29 | +import java.sql.Timestamp; | |
26 | 30 | import java.time.LocalDateTime; |
27 | 31 | import java.time.format.DateTimeFormatter; |
28 | 32 | import java.util.Date; |
29 | 33 | import java.util.List; |
34 | +import java.util.logging.Level; | |
35 | +import java.util.logging.Logger; | |
30 | 36 | import org.apache.wicket.ajax.AjaxRequestTarget; |
31 | 37 | import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior; |
32 | 38 | import org.apache.wicket.ajax.markup.html.form.AjaxButton; |
@@ -34,7 +40,6 @@ | ||
34 | 40 | import org.apache.wicket.datetime.markup.html.basic.DateLabel; |
35 | 41 | import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; |
36 | 42 | import org.apache.wicket.markup.html.form.Form; |
37 | -import org.apache.wicket.markup.html.form.TextField; | |
38 | 43 | import org.apache.wicket.model.AbstractReadOnlyModel; |
39 | 44 | import org.apache.wicket.model.IModel; |
40 | 45 | import org.apache.wicket.model.Model; |
@@ -41,9 +46,13 @@ | ||
41 | 46 | import org.apache.wicket.util.time.Duration; |
42 | 47 | import org.clearfy.ClearfyPage; |
43 | 48 | import org.clearfy.ClearfySection; |
49 | +import org.clearfy.admin.organization.data.OrganizationUserLink; | |
50 | +import org.clearfy.components.gapi.CurrentLocationPicker; | |
44 | 51 | import org.clearfy.components.tableview.Record; |
45 | 52 | import org.clearfy.components.tableview.ResultSetProvider; |
46 | 53 | import org.clearfy.components.tableview.TableView; |
54 | +import org.clearfy.plugin.employee.data.Employee; | |
55 | +import org.clearfy.plugin.timecard.data.TimeRecord; | |
47 | 56 | |
48 | 57 | /** |
49 | 58 | * |
@@ -57,14 +66,10 @@ | ||
57 | 66 | |
58 | 67 | private DateLabel currentTime; |
59 | 68 | |
69 | + private CurrentLocationPicker currentLocationPicker; | |
70 | + | |
60 | 71 | private AjaxButton timeRecordButton; |
61 | 72 | |
62 | - private TextField<String> latitude; | |
63 | - | |
64 | - private TextField<String> longitude; | |
65 | - | |
66 | - private TextField<String> accuracy; | |
67 | - | |
68 | 73 | private AjaxButton update1; |
69 | 74 | |
70 | 75 | private AjaxButton update2; |
@@ -98,28 +103,16 @@ | ||
98 | 103 | this.timeRecorder.add(this.currentTime); |
99 | 104 | this.add(this.timeRecorder); |
100 | 105 | |
101 | - this.latitude = new TextField<>("latitude", Model.of("LATITUDE")); | |
102 | - this.timeRecorder.add(this.latitude); | |
106 | + this.currentLocationPicker = new CurrentLocationPicker("currentLocationPicker", | |
107 | + this.page); | |
108 | + this.timeRecorder.add(this.currentLocationPicker); | |
103 | 109 | |
104 | - this.longitude = new TextField<>("longitude", Model.of("LONGITUDE")); | |
105 | - this.timeRecorder.add(this.longitude); | |
106 | - | |
107 | - this.accuracy = new TextField<>("accuracy", Model.of("ACCURACY")); | |
108 | - this.timeRecorder.add(this.accuracy); | |
109 | - | |
110 | 110 | this.timeRecordButton = new AjaxButton("timeRecordButton", Model.of(this |
111 | 111 | .getSentence("打刻"))) { |
112 | 112 | @Override |
113 | 113 | public void onSubmit(AjaxRequestTarget target, Form form) { |
114 | - String lat = latitude.getModelObject(); | |
115 | - String lon = longitude.getModelObject(); | |
116 | - String acc = accuracy.getModelObject(); | |
117 | - String now = currentTime.getDefaultModelObjectAsString(); | |
118 | - System.out.println( | |
119 | - String.format("%s %s %s %s", lat, lon, acc, now) | |
120 | - ); | |
114 | + TimeCardMain.this.timeRecord(target); | |
121 | 115 | } |
122 | - | |
123 | 116 | }; |
124 | 117 | this.timeRecorder.add(this.timeRecordButton); |
125 | 118 |
@@ -177,6 +170,80 @@ | ||
177 | 170 | |
178 | 171 | } |
179 | 172 | |
173 | + /** | |
174 | + * 打刻する | |
175 | + */ | |
176 | + private void timeRecord(AjaxRequestTarget target) { | |
177 | + | |
178 | + String lat = currentLocationPicker.getCoord( | |
179 | + CurrentLocationPicker.COORD_LATITUDE); | |
180 | + String lon = currentLocationPicker.getCoord( | |
181 | + CurrentLocationPicker.COORD_LONGITUDE); | |
182 | + String acc = currentLocationPicker.getCoord( | |
183 | + CurrentLocationPicker.COORD_ACCURACY); | |
184 | + String now = currentTime.getDefaultModelObjectAsString(); | |
185 | + System.out.println( | |
186 | + String.format("%s %s %s %s", lat, lon, acc, now) | |
187 | + ); | |
188 | + | |
189 | + LocalDateTime currentTime = LocalDateTime.now(); | |
190 | + java.sql.Date today = java.sql.Date.valueOf(currentTime.toLocalDate()); | |
191 | + Timestamp currenttimestamp = java.sql.Timestamp.valueOf(currentTime); | |
192 | + | |
193 | + int userId = Integer.valueOf(this.getCurrentSession() | |
194 | + .getUserId()); | |
195 | + | |
196 | + OrganizationUserLink organizationUserLink = new OrganizationUserLink(); | |
197 | + organizationUserLink.setJdbcSupplier(this.page); | |
198 | + ResultSet rs = organizationUserLink.select(organizationUserLink.UserId | |
199 | + .sameValueOf(userId)); | |
200 | + int orgId = -1; | |
201 | + try { | |
202 | + if (!rs.next()) { | |
203 | + return; | |
204 | + } | |
205 | + orgId = organizationUserLink.OrganizationId.of(rs); | |
206 | + rs.close(); | |
207 | + | |
208 | + } catch (SQLException ex) { | |
209 | + Logger.getLogger(TimeCardMain.class.getName()) | |
210 | + .log(Level.SEVERE, null, ex); | |
211 | + } | |
212 | + | |
213 | + Employee employee = new Employee(); | |
214 | + employee.setJdbcSupplier(this.page); | |
215 | + rs = employee.select(employee.UserId.sameValueOf(userId)); | |
216 | + | |
217 | + try { | |
218 | + if (rs.next()) { | |
219 | + int employeeId = employee.EmployeeId.of(rs); | |
220 | + | |
221 | + TimeRecord timeRecord = new TimeRecord(); | |
222 | + timeRecord.setJdbcSupplier(this.page); | |
223 | + timeRecord.clearValues(); | |
224 | + | |
225 | + timeRecord.Stamp.setValue(currenttimestamp); | |
226 | + timeRecord.Mdate.setValue(currenttimestamp); | |
227 | + timeRecord.Disable.setValue((short) 0); | |
228 | + timeRecord.CheckDate.setValue(today); | |
229 | + timeRecord.RecordDatetime.setValue(currenttimestamp); | |
230 | + timeRecord.OrganizationId.setValue(orgId); | |
231 | + timeRecord.EmployeeId.setValue(employeeId); | |
232 | + timeRecord.Latitude.setValue(new BigDecimal(lat)); | |
233 | + timeRecord.Longitude.setValue(new BigDecimal(lon)); | |
234 | + timeRecord.Accuracy.setValue(new BigDecimal(acc)); | |
235 | + timeRecord.Modified.setValue((short) 0); | |
236 | + | |
237 | + timeRecord.insert(); | |
238 | + | |
239 | + rs.close(); | |
240 | + } | |
241 | + } catch (SQLException ex) { | |
242 | + Logger.getLogger(TimeCardMain.class.getName()) | |
243 | + .log(Level.SEVERE, null, ex); | |
244 | + } | |
245 | + } | |
246 | + | |
180 | 247 | private void showCurrentRecord() { |
181 | 248 | |
182 | 249 | //this.recordList.clear(); |
@@ -23,6 +23,7 @@ | ||
23 | 23 | */ |
24 | 24 | package org.clearfy.plugin.timecard.data; |
25 | 25 | |
26 | +import java.math.BigDecimal; | |
26 | 27 | import java.sql.Date; |
27 | 28 | import java.sql.Timestamp; |
28 | 29 | import org.clearfy.admin.organization.data.Organization; |
@@ -82,6 +83,15 @@ | ||
82 | 83 | @LogicalName("メッセージキー") |
83 | 84 | public MD5Column MessageKey; |
84 | 85 | |
86 | + @LogicalName("緯度") | |
87 | + public Column<BigDecimal> Latitude; | |
88 | + | |
89 | + @LogicalName("経度") | |
90 | + public Column<BigDecimal> Longitude; | |
91 | + | |
92 | + @LogicalName("誤差") | |
93 | + public Column<BigDecimal> Accuracy; | |
94 | + | |
85 | 95 | @Override |
86 | 96 | public void defineColumns() { |
87 | 97 |
@@ -107,6 +117,14 @@ | ||
107 | 117 | |
108 | 118 | this.MessageKey.setAllowNull(true); //既存データとの兼ね合いがあるので、nullOK |
109 | 119 | |
120 | + this.Latitude.setLength(18, 9) | |
121 | + .setDefault("-1.0"); //既存データとの兼ね合いがあるので、nullOK | |
122 | + | |
123 | + this.Longitude.setLength(18, 9) | |
124 | + .setDefault("-1.0"); //既存データとの兼ね合いがあるので、nullOK | |
125 | + | |
126 | + this.Accuracy.setLength(18, 9) | |
127 | + .setDefault("-1.0"); //既存データとの兼ね合いがあるので、nullOK | |
110 | 128 | } |
111 | 129 | |
112 | 130 | } |
@@ -23,6 +23,7 @@ | ||
23 | 23 | */ |
24 | 24 | package org.clearfy.admin.organization.data; |
25 | 25 | |
26 | +import java.math.BigDecimal; | |
26 | 27 | import org.clearfy.annotations.Alias; |
27 | 28 | import org.clearfy.annotations.Comment; |
28 | 29 | import org.clearfy.annotations.LogicalName; |
@@ -84,6 +85,12 @@ | ||
84 | 85 | @LogicalName("ウェブサイト") |
85 | 86 | public Column<String> Website; |
86 | 87 | |
88 | + @LogicalName("緯度") | |
89 | + public Column<BigDecimal> Latitude; | |
90 | + | |
91 | + @LogicalName("経度") | |
92 | + public Column<BigDecimal> Longitude; | |
93 | + | |
87 | 94 | @Override |
88 | 95 | public void defineColumns() { |
89 | 96 |
@@ -113,6 +120,10 @@ | ||
113 | 120 | |
114 | 121 | this.Website.setLength(Column.SIZE_256); |
115 | 122 | |
123 | + this.Latitude.setLength(18, 9).setDefault("-1.0"); | |
124 | + | |
125 | + this.Longitude.setLength(18, 9).setDefault("-1.0"); | |
126 | + | |
116 | 127 | } |
117 | 128 | |
118 | 129 | } |
@@ -0,0 +1,150 @@ | ||
1 | +<!DOCTYPE html> | |
2 | +<!-- | |
3 | +The MIT License | |
4 | + | |
5 | +Copyright 2017 tmworks. | |
6 | + | |
7 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 | +of this software and associated documentation files (the "Software"), to deal | |
9 | +in the Software without restriction, including without limitation the rights | |
10 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | +copies of the Software, and to permit persons to whom the Software is | |
12 | +furnished to do so, subject to the following conditions: | |
13 | + | |
14 | +The above copyright notice and this permission notice shall be included in | |
15 | +all copies or substantial portions of the Software. | |
16 | + | |
17 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
23 | +THE SOFTWARE. | |
24 | +--> | |
25 | +<html xmlns="http://www.w3.org/1999/xhtml" | |
26 | + xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" | |
27 | + xml:lang="ja" | |
28 | + lang="ja"> | |
29 | + <head> | |
30 | + <meta charset="UTF-8"/> | |
31 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
32 | + </head> | |
33 | + <body> | |
34 | + <wicket:panel> | |
35 | + <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCY2EpuxW8aKPvtDVWt9wmqBPKRHRoPwTQ&callback=initMap" | |
36 | + async defer> | |
37 | + </script> | |
38 | + <form wicket:id="currentLocationPicker"> | |
39 | + <div class="locationpicker" > | |
40 | + <label class="localtionpicker title">現在位置</label> | |
41 | + <div class="localtionpicker map" name="map" style=""></div> | |
42 | + <div class="localtionpicker coordinates" name="localtionpicker.coordinates"> | |
43 | + <div> | |
44 | + <label class="locatitonpicker coordinates label">緯度</label> | |
45 | + <input type="text" class="locationpicker corrdinaltes parameter" name="latitude" wicket:id="latitude" value="緯度" /> | |
46 | + </div> | |
47 | + <div> | |
48 | + <label class="locatitonpicker coordinates label">経度</label> | |
49 | + <input type="text" class="locationpicker corrdinaltes parameter" name="longitude" wicket:id="longitude" value="経度"/> | |
50 | + </div> | |
51 | + <div> | |
52 | + <label class="locatitonpicker coordinates label">誤差</label> | |
53 | + <input type="text" class="locationpicker corrdinaltes parameter" name="accuracy" wicket:id="accuracy" value="誤差" /> | |
54 | + </div> | |
55 | + </div> | |
56 | + <input class="localtionpicker result" type="hidden" name="map_result" /> | |
57 | + <div class="localtionpicker message" name="show_result" /> | |
58 | + </div> | |
59 | + <script> | |
60 | + var currentPosition; | |
61 | + var map; | |
62 | + var marker; | |
63 | + function initMap() { | |
64 | + //ユーザーの現在の位置情報を取得 | |
65 | + navigator.geolocation.getCurrentPosition(successCallback, errorCallback); | |
66 | + } | |
67 | + | |
68 | + /***** ユーザーの現在の位置情報を取得 *****/ | |
69 | + function successCallback(position) { | |
70 | + currentPosition = position; | |
71 | + //wicketとの干渉を避けるため、getElementsByNameで操作 | |
72 | + document.getElementsByName('currentLocationPicker:currentLocationPicker:latitude')[0].value = | |
73 | + position.coords.latitude; | |
74 | + document.getElementsByName('currentLocationPicker:currentLocationPicker:longitude')[0].value = | |
75 | + position.coords.longitude; | |
76 | + document.getElementsByName('currentLocationPicker:currentLocationPicker:accuracy')[0].value = | |
77 | + position.coords.accuracy; | |
78 | + | |
79 | + var position = new google.maps.LatLng( | |
80 | + currentPosition.coords.latitude, | |
81 | + currentPosition.coords.longitude); | |
82 | + | |
83 | + var accuracy = currentPosition.coords.accuracy; | |
84 | + | |
85 | + var mapOptions = { | |
86 | + center: position, | |
87 | + zoom: 18, | |
88 | + mapTypeId: google.maps.MapTypeId.ROADMAP | |
89 | + }; | |
90 | + | |
91 | + map = new google.maps.Map(document.getElementsByName('map')[0], mapOptions); | |
92 | + var markerOptions = { | |
93 | + position: position, | |
94 | + map: map | |
95 | + }; | |
96 | + marker = new google.maps.Marker(markerOptions); | |
97 | + document.getElementsByName('map_result')[0].setAttribute("value", 0); | |
98 | + | |
99 | + var circleOptions = { | |
100 | + center: position, // 中心点(google.maps.LatLng) | |
101 | + fillColor: '#00AA00', // 塗りつぶし色 | |
102 | + fillOpacity: 0.1, // 塗りつぶし透過度(0: 透明 ⇔ 1:不透明) | |
103 | + map: map, // 表示させる地図(google.maps.Map) | |
104 | + radius: accuracy, // 半径(m) | |
105 | + strokeColor: '#008800', // 外周色 | |
106 | + strokeOpacity: 1, // 外周透過度(0: 透明 ⇔ 1:不透明) | |
107 | + strokeWeight: 1 // 外周太さ(ピクセル) | |
108 | + }; | |
109 | + | |
110 | + new google.maps.Circle(circleOptions); | |
111 | + | |
112 | + var wcall = wicketAjaxGet('$url$' + '$args$', | |
113 | + function () { | |
114 | + document.write("SUCCESS"); | |
115 | + }, | |
116 | + function () { | |
117 | + document.write("ERROR"); | |
118 | + } | |
119 | + ); | |
120 | + | |
121 | + } | |
122 | + | |
123 | + /***** 位置情報が取得できない場合 *****/ | |
124 | + function errorCallback(error) { | |
125 | + var err_msg = ""; | |
126 | + switch (error.code) | |
127 | + { | |
128 | + case 1: | |
129 | + err_msg = "位置情報の利用が許可されていません.<br>許可をすると当ページで打刻ができるようになります."; | |
130 | + break; | |
131 | + case 2: | |
132 | + err_msg = "デバイスの位置が判定できません"; | |
133 | + break; | |
134 | + case 3: | |
135 | + err_msg = "タイムアウトしました"; | |
136 | + break; | |
137 | + } | |
138 | + document.getElementsByName('map')[0].setAttribute("style", "display: none;"); | |
139 | + document.getElementsByName('localtionpicker.coordinates')[0].setAttribute("style", "display: none;"); | |
140 | + document.getElementsByName('map_result')[0].setAttribute("value", error.code); | |
141 | + document.getElementsByName("show_result")[0].innerHTML = err_msg; | |
142 | + //デバッグ用→ document.getElementById("show_result").innerHTML = error.message; | |
143 | + } | |
144 | + | |
145 | + </script> | |
146 | + </form> | |
147 | + | |
148 | + </wicket:panel> | |
149 | + </body> | |
150 | +</html> | |
\ No newline at end of file |
@@ -0,0 +1,105 @@ | ||
1 | +/* | |
2 | + * The MIT License | |
3 | + * | |
4 | + * Copyright 2018 tmworks. | |
5 | + * | |
6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | + * of this software and associated documentation files (the "Software"), to deal | |
8 | + * in the Software without restriction, including without limitation the rights | |
9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | + * copies of the Software, and to permit persons to whom the Software is | |
11 | + * furnished to do so, subject to the following conditions: | |
12 | + * | |
13 | + * The above copyright notice and this permission notice shall be included in | |
14 | + * all copies or substantial portions of the Software. | |
15 | + * | |
16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | + * THE SOFTWARE. | |
23 | + */ | |
24 | +package org.clearfy.components.gapi; | |
25 | + | |
26 | +import javax.json.Json; | |
27 | +import javax.json.JsonObject; | |
28 | +import org.apache.wicket.markup.html.form.Form; | |
29 | +import org.apache.wicket.markup.html.form.TextField; | |
30 | +import org.apache.wicket.model.Model; | |
31 | +import org.clearfy.ClearfyContentHolder; | |
32 | +import org.clearfy.ClearfyPage; | |
33 | + | |
34 | +/** | |
35 | + * 現在地を取得するコンポーネント | |
36 | + * | |
37 | + * @author Takahiro MURAKAMI | |
38 | + */ | |
39 | +public class CurrentLocationPicker extends ClearfyContentHolder { | |
40 | + | |
41 | + public static final int COORD_LATITUDE = 0; | |
42 | + | |
43 | + public static final int COORD_LONGITUDE = 1; | |
44 | + | |
45 | + public static final int COORD_ACCURACY = 2; | |
46 | + | |
47 | + private Form currentLocationPicker; | |
48 | + | |
49 | + private TextField<String> latitude; | |
50 | + private TextField<String> longitude; | |
51 | + private TextField<String> accuracy; | |
52 | + | |
53 | + public CurrentLocationPicker(String id, ClearfyPage page) { | |
54 | + super(id, page); | |
55 | + } | |
56 | + | |
57 | + @Override | |
58 | + public void drawContent() { | |
59 | + | |
60 | + this.currentLocationPicker = new Form("currentLocationPicker"); | |
61 | + | |
62 | + this.latitude = new TextField<>("latitude", Model.of("LATITUDE")); | |
63 | + this.currentLocationPicker.add(this.latitude); | |
64 | + | |
65 | + this.longitude = new TextField<>("longitude", Model.of("LONGITUDE")); | |
66 | + this.currentLocationPicker.add(this.longitude); | |
67 | + | |
68 | + this.accuracy = new TextField<>("accuracy", Model.of("ACCURACY")); | |
69 | + this.currentLocationPicker.add(this.accuracy); | |
70 | + | |
71 | + this.add(this.currentLocationPicker); | |
72 | + } | |
73 | + | |
74 | + @Override | |
75 | + public String getTitle() { | |
76 | + return this.getSentence("現在地ピッカー"); | |
77 | + } | |
78 | + | |
79 | + public String getCoord(int coordType) { | |
80 | + String rvalue = ""; | |
81 | + switch (coordType) { | |
82 | + case CurrentLocationPicker.COORD_LATITUDE: | |
83 | + rvalue = this.latitude.getModelObject(); | |
84 | + break; | |
85 | + case CurrentLocationPicker.COORD_LONGITUDE: | |
86 | + rvalue = this.longitude.getModelObject(); | |
87 | + break; | |
88 | + case CurrentLocationPicker.COORD_ACCURACY: | |
89 | + rvalue = this.accuracy.getModelObject(); | |
90 | + break; | |
91 | + } | |
92 | + return rvalue; | |
93 | + } | |
94 | + | |
95 | + public String getCoords() { | |
96 | + JsonObject root = Json.createObjectBuilder() | |
97 | + .add("latitude", this.getCoord(CurrentLocationPicker.COORD_LATITUDE)) | |
98 | + .add("longitude", this.getCoord(CurrentLocationPicker.COORD_LONGITUDE)) | |
99 | + .add("accuracy", this.getCoord(CurrentLocationPicker.COORD_ACCURACY)) | |
100 | + .build(); | |
101 | + return root.toString(); | |
102 | + | |
103 | + } | |
104 | + | |
105 | +} |
@@ -0,0 +1,137 @@ | ||
1 | +<!DOCTYPE html> | |
2 | +<!-- | |
3 | +The MIT License | |
4 | + | |
5 | +Copyright 2017 tmworks. | |
6 | + | |
7 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 | +of this software and associated documentation files (the "Software"), to deal | |
9 | +in the Software without restriction, including without limitation the rights | |
10 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | +copies of the Software, and to permit persons to whom the Software is | |
12 | +furnished to do so, subject to the following conditions: | |
13 | + | |
14 | +The above copyright notice and this permission notice shall be included in | |
15 | +all copies or substantial portions of the Software. | |
16 | + | |
17 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
23 | +THE SOFTWARE. | |
24 | +--> | |
25 | +<html xmlns="http://www.w3.org/1999/xhtml" | |
26 | + xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" | |
27 | + xml:lang="ja" | |
28 | + lang="ja"> | |
29 | + <head> | |
30 | + <meta charset="UTF-8"/> | |
31 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
32 | + </head> | |
33 | + <body> | |
34 | + <wicket:panel> | |
35 | + <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCY2EpuxW8aKPvtDVWt9wmqBPKRHRoPwTQ&callback=initMap" | |
36 | + async defer> | |
37 | + </script> | |
38 | + <form wicket:id="locationViewer"> | |
39 | + <div class="locationpicker" > | |
40 | + <label class="localtionpicker title">現在位置</label> | |
41 | + <div class="localtionpicker map" name="map" style=""></div> | |
42 | + <div class="localtionpicker coordinates" name="localtionpicker.coordinates"> | |
43 | + <div> | |
44 | + <label class="locatitonpicker coordinates label">緯度</label> | |
45 | + <input type="text" class="locationpicker corrdinaltes parameter" name="latitude" wicket:id="latitude" value="緯度" /> | |
46 | + </div> | |
47 | + <div> | |
48 | + <label class="locatitonpicker coordinates label">経度</label> | |
49 | + <input type="text" class="locationpicker corrdinaltes parameter" name="longitude" wicket:id="longitude" value="経度"/> | |
50 | + </div> | |
51 | + <div> | |
52 | + <label class="locatitonpicker coordinates label">誤差</label> | |
53 | + <input type="text" class="locationpicker corrdinaltes parameter" name="accuracy" wicket:id="accuracy" value="誤差" /> | |
54 | + </div> | |
55 | + </div> | |
56 | + <input class="localtionpicker result" type="hidden" name="map_result" /> | |
57 | + <div class="localtionpicker message" name="show_result" /> | |
58 | + </div> | |
59 | + <script> | |
60 | + var currentPosition; | |
61 | + var map; | |
62 | + var marker; | |
63 | + | |
64 | + function initMap() { | |
65 | + //ユーザーの現在の位置情報を取得 | |
66 | + navigator.geolocation.getCurrentPosition(successCallback, errorCallback); | |
67 | + } | |
68 | + | |
69 | + /** | |
70 | + * ユーザーの現在の位置情報を取得 | |
71 | + */ | |
72 | + function successCallback(position) { | |
73 | + | |
74 | + var position = new google.maps.LatLng( | |
75 | + document.getElementsByName('currentLocationPicker:currentLocationPicker:latitude')[0].value, | |
76 | + document.getElementsByName('currentLocationPicker:currentLocationPicker:longitude')[0].value | |
77 | + ); | |
78 | + | |
79 | + var mapOptions = { | |
80 | + center: position, | |
81 | + zoom: 18, | |
82 | + mapTypeId: google.maps.MapTypeId.ROADMAP | |
83 | + }; | |
84 | + | |
85 | + map = new google.maps.Map( | |
86 | + document.getElementsByName('map')[0], mapOptions | |
87 | + ); | |
88 | + var markerOptions = { | |
89 | + position: position, | |
90 | + map: map | |
91 | + }; | |
92 | + marker = new google.maps.Marker(markerOptions); | |
93 | + document.getElementsByName('map_result')[0].setAttribute("value", 0); | |
94 | + | |
95 | + var circleOptions = { | |
96 | + center: position, | |
97 | + fillColor: '#00AA00', | |
98 | + fillOpacity: 0.1, | |
99 | + map: map, | |
100 | + radius: accuracy, | |
101 | + strokeColor: '#008800', | |
102 | + strokeOpacity: 1, | |
103 | + strokeWeight: 1 | |
104 | + }; | |
105 | + | |
106 | + new google.maps.Circle(circleOptions); | |
107 | + | |
108 | + } | |
109 | + | |
110 | + /***** 位置情報が取得できない場合 *****/ | |
111 | + function errorCallback(error) { | |
112 | + var err_msg = ""; | |
113 | + switch (error.code) | |
114 | + { | |
115 | + case 1: | |
116 | + err_msg = "位置情報の利用が許可されていません.<br>許可をすると当ページで打刻ができるようになります."; | |
117 | + break; | |
118 | + case 2: | |
119 | + err_msg = "デバイスの位置が判定できません"; | |
120 | + break; | |
121 | + case 3: | |
122 | + err_msg = "タイムアウトしました"; | |
123 | + break; | |
124 | + } | |
125 | + document.getElementsByName('map')[0].setAttribute("style", "display: none;"); | |
126 | + document.getElementsByName('localtionpicker.coordinates')[0].setAttribute("style", "display: none;"); | |
127 | + document.getElementsByName('map_result')[0].setAttribute("value", error.code); | |
128 | + document.getElementsByName("show_result")[0].innerHTML = err_msg; | |
129 | + //デバッグ用→ document.getElementById("show_result").innerHTML = error.message; | |
130 | + } | |
131 | + | |
132 | + </script> | |
133 | + </form> | |
134 | + | |
135 | + </wicket:panel> | |
136 | + </body> | |
137 | +</html> | |
\ No newline at end of file |
@@ -0,0 +1,85 @@ | ||
1 | +/* | |
2 | + * The MIT License | |
3 | + * | |
4 | + * Copyright 2018 tmworks. | |
5 | + * | |
6 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | + * of this software and associated documentation files (the "Software"), to deal | |
8 | + * in the Software without restriction, including without limitation the rights | |
9 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | + * copies of the Software, and to permit persons to whom the Software is | |
11 | + * furnished to do so, subject to the following conditions: | |
12 | + * | |
13 | + * The above copyright notice and this permission notice shall be included in | |
14 | + * all copies or substantial portions of the Software. | |
15 | + * | |
16 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | + * THE SOFTWARE. | |
23 | + */ | |
24 | +package org.clearfy.components.gapi; | |
25 | + | |
26 | +import java.math.BigDecimal; | |
27 | +import org.apache.wicket.markup.html.form.Form; | |
28 | +import org.apache.wicket.markup.html.form.TextField; | |
29 | +import org.apache.wicket.model.Model; | |
30 | +import org.clearfy.ClearfyContentHolder; | |
31 | +import org.clearfy.ClearfyPage; | |
32 | + | |
33 | +/** | |
34 | + * 現在地を取得するコンポーネント | |
35 | + * | |
36 | + * @author Takahiro MURAKAMI | |
37 | + */ | |
38 | +public class LocationViewer extends ClearfyContentHolder { | |
39 | + | |
40 | + private Form locationViewer; | |
41 | + | |
42 | + private TextField<String> latitude; | |
43 | + private TextField<String> longitude; | |
44 | + private TextField<String> accuracy; | |
45 | + | |
46 | + public LocationViewer(String id, ClearfyPage page) { | |
47 | + super(id, page); | |
48 | + } | |
49 | + | |
50 | + @Override | |
51 | + public void drawContent() { | |
52 | + | |
53 | + this.locationViewer = new Form("locationViewer"); | |
54 | + | |
55 | + this.latitude = new TextField<>("latitude", Model.of("LATITUDE")); | |
56 | + this.locationViewer.add(this.latitude); | |
57 | + | |
58 | + this.longitude = new TextField<>("longitude", Model.of("LONGITUDE")); | |
59 | + this.locationViewer.add(this.longitude); | |
60 | + | |
61 | + this.accuracy = new TextField<>("accuracy", Model.of("ACCURACY")); | |
62 | + this.locationViewer.add(this.accuracy); | |
63 | + | |
64 | + this.add(this.locationViewer); | |
65 | + } | |
66 | + | |
67 | + @Override | |
68 | + public String getTitle() { | |
69 | + return this.getSentence("地図"); | |
70 | + } | |
71 | + | |
72 | + /** | |
73 | + * 地図の中心座標を指定する。 | |
74 | + * | |
75 | + * @param latitude 緯度 | |
76 | + * @param longitude 経度 | |
77 | + * @param accuracy 誤差 | |
78 | + */ | |
79 | + public void setCoord(BigDecimal latitude, BigDecimal longitude, BigDecimal accuracy) { | |
80 | + this.latitude.setModelObject(latitude.toString()); | |
81 | + this.longitude.setModelObject(longitude.toString()); | |
82 | + this.accuracy.setModelObject(accuracy.toString()); | |
83 | + } | |
84 | + | |
85 | +} |