Repository: oasis-open/cti-python-stix2
Pull request #253 (2019-02-08 14:39:19)

Location issue 86


Patch:
diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py
index 37699a6..cff8ba6 100644
--- a/stix2/v21/sdo.py
+++ b/stix2/v21/sdo.py
@@ -3,6 +3,8 @@
 from collections import OrderedDict
 import itertools
 
+from six.moves.urllib.parse import quote_plus
+
 from ..core import STIXDomainObject
 from ..custom import _custom_object_builder
 from ..properties import (
@@ -263,6 +265,45 @@ class Location(STIXDomainObject):
         self._check_properties_dependency(['latitude'], ['longitude'])
         self._check_properties_dependency(['longitude'], ['latitude'])
 
+    def to_maps_url(self, map_engine="Google Maps"):
+        params = []
+
+        latitude = self.get('latitude', None)
+        longitude = self.get('longitude', None)
+        if latitude is not None and longitude is not None:
+            params.extend([str(latitude), str(longitude)])
+        else:
+            properties = ['street_address', 'city', 'country', 'region', 'administrative_area', 'postal_code']
+            params = [self.get(prop) for prop in properties if self.get(prop) is not None]
+
+        return self._to_maps_url_dispatcher(map_engine, params)
+
+    def _to_maps_url_dispatcher(self, map_engine, params):
+        if map_engine == "Google Maps":
+            return self._to_google_maps_url(params)
+        elif map_engine == "Bing Maps":
+            return self._to_bing_maps_url(params)
+        else:
+            raise ValueError(map_engine + " is not a valid or currently-supported map engine")
+
+    def _to_google_maps_url(self, params):
+        url_base = "https://www.google.com/maps/search/?api=1&query="
+        url_ending = params[0]
+        for i in range(1, len(params)):
+            url_ending = url_ending + "," + params[i]
+
+        final_url = url_base + quote_plus(url_ending)
+        return final_url
+
+    def _to_bing_maps_url(self, params):
+        url_base = "https://bing.com/maps/default.aspx?where1="
+        url_ending = params[0]
+        for i in range(1, len(params)):
+            url_ending = url_ending + "," + params[i]
+
+        final_url = url_base + quote_plus(url_ending) + "&lvl=16"   # level 16 zoom so long/lat searches shown more clearly
+        return final_url
+
 
 class Malware(STIXDomainObject):
     # TODO: Add link


Test patch:
diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py
index 5a4e17a..c8bf0fc 100644
--- a/stix2/test/v21/test_location.py
+++ b/stix2/test/v21/test_location.py
@@ -263,3 +263,131 @@ def test_location_lat_or_lon_dependency_missing(data, msg):
         stix2.parse(data)
 
     assert msg in str(excinfo.value)
+
+
+def test_google_map_url_long_lat_provided():
+    EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001"
+    now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc)
+
+    loc = stix2.v21.Location(
+        type="location",
+        id=LOCATION_ID,
+        created=now,
+        modified=now,
+        latitude=41.862401,
+        longitude=-87.616001,
+    )
+
+    loc_url = loc.to_maps_url()
+    assert loc_url == EXPECTED_URL
+
+
+def test_google_map_url_multiple_props_no_long_lat_provided():
+    EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America"
+    now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc)
+
+    loc = stix2.v21.Location(
+        type="location",
+        id=LOCATION_ID,
+        created=now,
+        modified=now,
+        region="North America",
+        country="United States of America",
+        street_address="1410 Museum Campus Drive, Chicago, IL 60605",
+    )
+
+    loc_url = loc.to_maps_url()
+    assert loc_url == EXPECTED_URL
+
+
+def test_google_map_url_multiple_props_and_long_lat_provided():
+    EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001"
+    now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc)
+
+    loc = stix2.v21.Location(
+        type="location",
+        id=LOCATION_ID,
+        created=now,
+        modified=now,
+        region="North America",
+        country="United States of America",
+        street_address="1410 Museum Campus Drive, Chicago, IL 60605",
+        latitude=41.862401,
+        longitude=-87.616001,
+    )
+
+    loc_url = loc.to_maps_url()
+    assert loc_url == EXPECTED_URL
+
+
+def test_map_url_invalid_map_engine_provided():
+    now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc)
+
+    loc = stix2.v21.Location(
+        type="location",
+        id=LOCATION_ID,
+        created=now,
+        modified=now,
+        latitude=41.862401,
+        longitude=-87.616001,
+    )
+
+    with pytest.raises(ValueError) as excinfo:
+        loc.to_maps_url("Fake Maps")
+
+    assert "is not a valid or currently-supported map engine" in str(excinfo.value)
+
+
+def test_bing_map_url_long_lat_provided():
+    EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16"
+    now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc)
+
+    loc = stix2.v21.Location(
+        type="location",
+        id=LOCATION_ID,
+        created=now,
+        modified=now,
+        latitude=41.862401,
+        longitude=-87.616001,
+    )
+
+    loc_url = loc.to_maps_url("Bing Maps")
+    assert loc_url == EXPECTED_URL
+
+
+def test_bing_map_url_multiple_props_no_long_lat_provided():
+    EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America&lvl=16"
+    now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc)
+
+    loc = stix2.v21.Location(
+        type="location",
+        id=LOCATION_ID,
+        created=now,
+        modified=now,
+        region="North America",
+        country="United States of America",
+        street_address="1410 Museum Campus Drive, Chicago, IL 60605",
+    )
+
+    loc_url = loc.to_maps_url("Bing Maps")
+    assert loc_url == EXPECTED_URL
+
+
+def test_bing_map_url_multiple_props_and_long_lat_provided():
+    EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16"
+    now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc)
+
+    loc = stix2.v21.Location(
+        type="location",
+        id=LOCATION_ID,
+        created=now,
+        modified=now,
+        region="North America",
+        country="United States of America",
+        street_address="1410 Museum Campus Drive, Chicago, IL 60605",
+        latitude=41.862401,
+        longitude=-87.616001,
+    )
+
+    loc_url = loc.to_maps_url("Bing Maps")
+    assert loc_url == EXPECTED_URL