[ofbiz-framework] branch trunk updated: Improved: Added support to calculate distance between two geo points. (OFBIZ-11901) Thanks Ravi Lodhi for review and discussion.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[ofbiz-framework] branch trunk updated: Improved: Added support to calculate distance between two geo points. (OFBIZ-11901) Thanks Ravi Lodhi for review and discussion.

surajk
This is an automated email from the ASF dual-hosted git repository.

surajk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new cc17887  Improved: Added support to calculate distance between two geo points. (OFBIZ-11901) Thanks Ravi Lodhi for review and discussion.
cc17887 is described below

commit cc178879809b12bd647aed6f9500ab6b254da27c
Author: Suraj Khurana <[hidden email]>
AuthorDate: Sat Jan 9 13:37:21 2021 +0530

    Improved: Added support to calculate distance between two geo points.
    (OFBIZ-11901)
    Thanks Ravi Lodhi for review and discussion.
---
 framework/common/servicedef/services_geo.xml       |  8 ++++
 .../org/apache/ofbiz/common/geo/GeoServices.java   | 55 ++++++++++++++++++++++
 .../org/apache/ofbiz/common/geo/GeoWorker.java     | 11 +++++
 3 files changed, 74 insertions(+)

diff --git a/framework/common/servicedef/services_geo.xml b/framework/common/servicedef/services_geo.xml
index 1d9ea0d..c5753f2 100644
--- a/framework/common/servicedef/services_geo.xml
+++ b/framework/common/servicedef/services_geo.xml
@@ -83,4 +83,12 @@ under the License.
         <description>Delete a Country Address Format</description>
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
+
+    <service name="getDistanceBetweenGeoPoints" engine="java" location="org.apache.ofbiz.common.geo.GeoServices" auth="false" invoke="getDistanceBetweenGeoPoints">
+        <attribute name="fromLatitude" mode="IN" type="Double"/>
+        <attribute name="fromLongitude" mode="IN" type="Double"/>
+        <attribute name="toLatitude" mode="IN" type="Double"/>
+        <attribute name="toLongitude" mode="IN" type="Double"/>
+        <attribute name="distance" mode="OUT" type="Double"/>
+    </service>
 </services>
diff --git a/framework/common/src/main/java/org/apache/ofbiz/common/geo/GeoServices.java b/framework/common/src/main/java/org/apache/ofbiz/common/geo/GeoServices.java
new file mode 100644
index 0000000..f95f3c7
--- /dev/null
+++ b/framework/common/src/main/java/org/apache/ofbiz/common/geo/GeoServices.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ofbiz.common.geo;
+
+import org.apache.ofbiz.base.util.UtilMisc;
+import org.apache.ofbiz.service.DispatchContext;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+public class GeoServices {
+
+    private static final double RADIUS_OF_EARTH = 6371; // Radius of the earth in km
+    private static final double MILES_PER_KILOMETER = 0.621371192; // TODO: Think upon using convertUom service
+
+    public static Map<String, Object> getDistanceBetweenGeoPoints(DispatchContext dctx, Map<String, ? extends Object> context) {
+        Map<String, Object> serviceResponse = new HashMap<>();
+
+        double fromLatitude = UtilMisc.toDouble(context.get("fromLatitude"));
+        double fromLongitude = UtilMisc.toDouble(context.get("fromLongitude"));
+        double toLatitude = UtilMisc.toDouble(context.get("toLatitude"));
+        double toLongitude = UtilMisc.toDouble(context.get("toLongitude"));
+
+        double dLatitude = Math.toRadians(toLatitude - fromLatitude);
+        double dLongitude = Math.toRadians(toLongitude - fromLongitude);
+        double a = Math.sin(dLatitude / 2) * Math.sin(dLatitude / 2)
+                + Math.cos(Math.toRadians(fromLatitude)) * Math.cos(Math.toRadians(toLatitude))
+                * Math.sin(dLongitude / 2) * Math.sin(dLongitude / 2);
+        double c = 2 * Math.atan(Math.sqrt(a) / Math.sqrt(1 - a));
+        double distance = c * RADIUS_OF_EARTH; // Distance in Kilometers
+        Locale locale = (Locale) context.get("locale");
+        if ("IMPERIAL".equals(GeoWorker.getMeasurementSystem(locale))) {
+            distance = distance * MILES_PER_KILOMETER; // Distance in Miles
+        }
+        serviceResponse.put("distance", distance);
+        return serviceResponse;
+    }
+}
diff --git a/framework/common/src/main/java/org/apache/ofbiz/common/geo/GeoWorker.java b/framework/common/src/main/java/org/apache/ofbiz/common/geo/GeoWorker.java
index ed16f4e..bba5a49 100644
--- a/framework/common/src/main/java/org/apache/ofbiz/common/geo/GeoWorker.java
+++ b/framework/common/src/main/java/org/apache/ofbiz/common/geo/GeoWorker.java
@@ -22,7 +22,10 @@ import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Locale;
 
+import com.ibm.icu.util.LocaleData;
+import com.ibm.icu.util.ULocale;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.UtilMisc;
 import org.apache.ofbiz.base.util.UtilValidate;
@@ -148,4 +151,12 @@ public final class GeoWorker {
         }
         return null;
     }
+    public static String getMeasurementSystem(Locale locale) {
+        ULocale loc = new ULocale(locale.toString());
+        LocaleData.MeasurementSystem measurementSystem = LocaleData.getMeasurementSystem(loc);
+        if (measurementSystem.equals(LocaleData.MeasurementSystem.US)) {
+            return "IMPERIAL";
+        }
+        return "METRIC";
+    }
 }