|
|
@ -1,12 +1,12 @@ |
|
|
|
# Support for the GeoRSS format |
|
|
|
# Copyright 2010-2015 Kurt McKee <contactme@kurtmckee.org> |
|
|
|
# Copyright 2010-2019 Kurt McKee <contactme@kurtmckee.org> |
|
|
|
# Copyright 2002-2008 Mark Pilgrim |
|
|
|
# All rights reserved. |
|
|
|
# |
|
|
|
# This file is a part of feedparser. |
|
|
|
# |
|
|
|
# Redistribution and use in source and binary forms, with or without modification, |
|
|
|
# are permitted provided that the following conditions are met: |
|
|
|
# Redistribution and use in source and binary forms, with or without |
|
|
|
# modification, are permitted provided that the following conditions are met: |
|
|
|
# |
|
|
|
# * Redistributions of source code must retain the above copyright notice, |
|
|
|
# this list of conditions and the following disclaimer. |
|
|
@ -26,10 +26,12 @@ |
|
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
|
|
# POSSIBILITY OF SUCH DAMAGE. |
|
|
|
|
|
|
|
from __future__ import absolute_import, unicode_literals |
|
|
|
from __future__ import absolute_import |
|
|
|
from __future__ import unicode_literals |
|
|
|
|
|
|
|
from ..util import FeedParserDict |
|
|
|
|
|
|
|
|
|
|
|
class Namespace(object): |
|
|
|
supported_namespaces = { |
|
|
|
'http://www.w3.org/2003/01/geo/wgs84_pos#': 'geo', |
|
|
@ -41,9 +43,9 @@ class Namespace(object): |
|
|
|
self.ingeometry = 0 |
|
|
|
super(Namespace, self).__init__() |
|
|
|
|
|
|
|
def _start_georssgeom(self, attrsD): |
|
|
|
def _start_georssgeom(self, attrs_d): |
|
|
|
self.push('geometry', 0) |
|
|
|
context = self._getContext() |
|
|
|
context = self._get_context() |
|
|
|
context['where'] = FeedParserDict() |
|
|
|
|
|
|
|
_start_georss_point = _start_georssgeom |
|
|
@ -52,7 +54,7 @@ class Namespace(object): |
|
|
|
_start_georss_box = _start_georssgeom |
|
|
|
|
|
|
|
def _save_where(self, geometry): |
|
|
|
context = self._getContext() |
|
|
|
context = self._get_context() |
|
|
|
context['where'].update(geometry) |
|
|
|
|
|
|
|
def _end_georss_point(self): |
|
|
@ -76,73 +78,73 @@ class Namespace(object): |
|
|
|
if geometry: |
|
|
|
self._save_where(geometry) |
|
|
|
|
|
|
|
def _start_where(self, attrsD): |
|
|
|
def _start_where(self, attrs_d): |
|
|
|
self.push('where', 0) |
|
|
|
context = self._getContext() |
|
|
|
context = self._get_context() |
|
|
|
context['where'] = FeedParserDict() |
|
|
|
_start_georss_where = _start_where |
|
|
|
|
|
|
|
def _parse_srs_attrs(self, attrsD): |
|
|
|
srsName = attrsD.get('srsname') |
|
|
|
def _parse_srs_attrs(self, attrs_d): |
|
|
|
srs_name = attrs_d.get('srsname') |
|
|
|
try: |
|
|
|
srsDimension = int(attrsD.get('srsdimension', '2')) |
|
|
|
srs_dimension = int(attrs_d.get('srsdimension', '2')) |
|
|
|
except ValueError: |
|
|
|
srsDimension = 2 |
|
|
|
context = self._getContext() |
|
|
|
context['where']['srsName'] = srsName |
|
|
|
context['where']['srsDimension'] = srsDimension |
|
|
|
srs_dimension = 2 |
|
|
|
context = self._get_context() |
|
|
|
context['where']['srsName'] = srs_name |
|
|
|
context['where']['srsDimension'] = srs_dimension |
|
|
|
|
|
|
|
def _start_gml_point(self, attrsD): |
|
|
|
self._parse_srs_attrs(attrsD) |
|
|
|
def _start_gml_point(self, attrs_d): |
|
|
|
self._parse_srs_attrs(attrs_d) |
|
|
|
self.ingeometry = 1 |
|
|
|
self.push('geometry', 0) |
|
|
|
|
|
|
|
def _start_gml_linestring(self, attrsD): |
|
|
|
self._parse_srs_attrs(attrsD) |
|
|
|
def _start_gml_linestring(self, attrs_d): |
|
|
|
self._parse_srs_attrs(attrs_d) |
|
|
|
self.ingeometry = 'linestring' |
|
|
|
self.push('geometry', 0) |
|
|
|
|
|
|
|
def _start_gml_polygon(self, attrsD): |
|
|
|
self._parse_srs_attrs(attrsD) |
|
|
|
def _start_gml_polygon(self, attrs_d): |
|
|
|
self._parse_srs_attrs(attrs_d) |
|
|
|
self.push('geometry', 0) |
|
|
|
|
|
|
|
def _start_gml_exterior(self, attrsD): |
|
|
|
def _start_gml_exterior(self, attrs_d): |
|
|
|
self.push('geometry', 0) |
|
|
|
|
|
|
|
def _start_gml_linearring(self, attrsD): |
|
|
|
def _start_gml_linearring(self, attrs_d): |
|
|
|
self.ingeometry = 'polygon' |
|
|
|
self.push('geometry', 0) |
|
|
|
|
|
|
|
def _start_gml_pos(self, attrsD): |
|
|
|
def _start_gml_pos(self, attrs_d): |
|
|
|
self.push('pos', 0) |
|
|
|
|
|
|
|
def _end_gml_pos(self): |
|
|
|
this = self.pop('pos') |
|
|
|
context = self._getContext() |
|
|
|
srsName = context['where'].get('srsName') |
|
|
|
srsDimension = context['where'].get('srsDimension', 2) |
|
|
|
context = self._get_context() |
|
|
|
srs_name = context['where'].get('srsName') |
|
|
|
srs_dimension = context['where'].get('srsDimension', 2) |
|
|
|
swap = True |
|
|
|
if srsName and "EPSG" in srsName: |
|
|
|
epsg = int(srsName.split(":")[-1]) |
|
|
|
if srs_name and "EPSG" in srs_name: |
|
|
|
epsg = int(srs_name.split(":")[-1]) |
|
|
|
swap = bool(epsg in _geogCS) |
|
|
|
geometry = _parse_georss_point(this, swap=swap, dims=srsDimension) |
|
|
|
geometry = _parse_georss_point(this, swap=swap, dims=srs_dimension) |
|
|
|
if geometry: |
|
|
|
self._save_where(geometry) |
|
|
|
|
|
|
|
def _start_gml_poslist(self, attrsD): |
|
|
|
def _start_gml_poslist(self, attrs_d): |
|
|
|
self.push('pos', 0) |
|
|
|
|
|
|
|
def _end_gml_poslist(self): |
|
|
|
this = self.pop('pos') |
|
|
|
context = self._getContext() |
|
|
|
srsName = context['where'].get('srsName') |
|
|
|
srsDimension = context['where'].get('srsDimension', 2) |
|
|
|
context = self._get_context() |
|
|
|
srs_name = context['where'].get('srsName') |
|
|
|
srs_dimension = context['where'].get('srsDimension', 2) |
|
|
|
swap = True |
|
|
|
if srsName and "EPSG" in srsName: |
|
|
|
epsg = int(srsName.split(":")[-1]) |
|
|
|
if srs_name and "EPSG" in srs_name: |
|
|
|
epsg = int(srs_name.split(":")[-1]) |
|
|
|
swap = bool(epsg in _geogCS) |
|
|
|
geometry = _parse_poslist( |
|
|
|
this, self.ingeometry, swap=swap, dims=srsDimension) |
|
|
|
this, self.ingeometry, swap=swap, dims=srs_dimension) |
|
|
|
if geometry: |
|
|
|
self._save_where(geometry) |
|
|
|
|
|
|
@ -172,10 +174,11 @@ def _parse_poslist(value, geom_type, swap=True, dims=2): |
|
|
|
else: |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
def _gen_georss_coords(value, swap=True, dims=2): |
|
|
|
# A generator of (lon, lat) pairs from a string of encoded GeoRSS |
|
|
|
# coordinates. Converts to floats and swaps order. |
|
|
|
latlons = ( float(ll) for ll in value.replace(',', ' ').split() ) |
|
|
|
latlons = (float(ll) for ll in value.replace(',', ' ').split()) |
|
|
|
while True: |
|
|
|
try: |
|
|
|
t = [next(latlons), next(latlons)][::swap and -1 or 1] |
|
|
@ -185,6 +188,7 @@ def _gen_georss_coords(value, swap=True, dims=2): |
|
|
|
except StopIteration: |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
def _parse_georss_point(value, swap=True, dims=2): |
|
|
|
# A point contains a single latitude-longitude pair, separated by |
|
|
|
# whitespace. We'll also handle comma separators. |
|
|
@ -194,6 +198,7 @@ def _parse_georss_point(value, swap=True, dims=2): |
|
|
|
except (IndexError, ValueError): |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
def _parse_georss_line(value, swap=True, dims=2): |
|
|
|
# A line contains a space separated list of latitude-longitude pairs in |
|
|
|
# WGS84 coordinate reference system, with each pair separated by |
|
|
@ -204,6 +209,7 @@ def _parse_georss_line(value, swap=True, dims=2): |
|
|
|
except (IndexError, ValueError): |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
def _parse_georss_polygon(value, swap=True, dims=2): |
|
|
|
# A polygon contains a space separated list of latitude-longitude pairs, |
|
|
|
# with each pair separated by whitespace. There must be at least four |
|
|
@ -217,6 +223,7 @@ def _parse_georss_polygon(value, swap=True, dims=2): |
|
|
|
return None |
|
|
|
return {'type': 'Polygon', 'coordinates': (ring,)} |
|
|
|
|
|
|
|
|
|
|
|
def _parse_georss_box(value, swap=True, dims=2): |
|
|
|
# A bounding box is a rectangular region, often used to define the extents |
|
|
|
# of a map or a rough area of interest. A box contains two space separate |
|
|
@ -228,40 +235,42 @@ def _parse_georss_box(value, swap=True, dims=2): |
|
|
|
except (IndexError, ValueError): |
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
# The list of EPSG codes for geographic (latitude/longitude) coordinate |
|
|
|
# systems to support decoding of GeoRSS GML profiles. |
|
|
|
_geogCS = [ |
|
|
|
3819, 3821, 3824, 3889, 3906, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, |
|
|
|
4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4018, 4019, 4020, 4021, 4022, |
|
|
|
4023, 4024, 4025, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, |
|
|
|
4041, 4042, 4043, 4044, 4045, 4046, 4047, 4052, 4053, 4054, 4055, 4075, 4081, |
|
|
|
4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, |
|
|
|
4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, 4145, |
|
|
|
4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, |
|
|
|
4159, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, |
|
|
|
4172, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, |
|
|
|
4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, |
|
|
|
4201, 4202, 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, |
|
|
|
4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226, 4227, |
|
|
|
4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, 4240, |
|
|
|
4241, 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252, 4253, |
|
|
|
4254, 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, |
|
|
|
4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, |
|
|
|
4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4291, 4292, 4293, |
|
|
|
4294, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, |
|
|
|
4308, 4309, 4310, 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, |
|
|
|
4324, 4326, 4463, 4470, 4475, 4483, 4490, 4555, 4558, 4600, 4601, 4602, 4603, |
|
|
|
4604, 4605, 4606, 4607, 4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, |
|
|
|
4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, 4628, 4629, |
|
|
|
4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639, 4640, 4641, 4642, |
|
|
|
4643, 4644, 4645, 4646, 4657, 4658, 4659, 4660, 4661, 4662, 4663, 4664, 4665, |
|
|
|
4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, |
|
|
|
4679, 4680, 4681, 4682, 4683, 4684, 4685, 4686, 4687, 4688, 4689, 4690, 4691, |
|
|
|
4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703, 4704, |
|
|
|
4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, |
|
|
|
4718, 4719, 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, |
|
|
|
4731, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, 4740, 4741, 4742, 4743, |
|
|
|
4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, |
|
|
|
4757, 4758, 4759, 4760, 4761, 4762, 4763, 4764, 4765, 4801, 4802, 4803, 4804, |
|
|
|
4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, |
|
|
|
4819, 4820, 4821, 4823, 4824, 4901, 4902, 4903, 4904, 4979 ] |
|
|
|
3819, 3821, 3824, 3889, 3906, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, |
|
|
|
4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4018, 4019, 4020, 4021, 4022, |
|
|
|
4023, 4024, 4025, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, |
|
|
|
4041, 4042, 4043, 4044, 4045, 4046, 4047, 4052, 4053, 4054, 4055, 4075, 4081, |
|
|
|
4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, |
|
|
|
4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, 4145, |
|
|
|
4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, |
|
|
|
4159, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, |
|
|
|
4172, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, |
|
|
|
4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, |
|
|
|
4201, 4202, 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, |
|
|
|
4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226, 4227, |
|
|
|
4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, 4240, |
|
|
|
4241, 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252, 4253, |
|
|
|
4254, 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, |
|
|
|
4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, |
|
|
|
4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4291, 4292, 4293, |
|
|
|
4294, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, |
|
|
|
4308, 4309, 4310, 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, |
|
|
|
4324, 4326, 4463, 4470, 4475, 4483, 4490, 4555, 4558, 4600, 4601, 4602, 4603, |
|
|
|
4604, 4605, 4606, 4607, 4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, |
|
|
|
4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, 4628, 4629, |
|
|
|
4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639, 4640, 4641, 4642, |
|
|
|
4643, 4644, 4645, 4646, 4657, 4658, 4659, 4660, 4661, 4662, 4663, 4664, 4665, |
|
|
|
4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, |
|
|
|
4679, 4680, 4681, 4682, 4683, 4684, 4685, 4686, 4687, 4688, 4689, 4690, 4691, |
|
|
|
4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703, 4704, |
|
|
|
4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, |
|
|
|
4718, 4719, 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, |
|
|
|
4731, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, 4740, 4741, 4742, 4743, |
|
|
|
4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, |
|
|
|
4757, 4758, 4759, 4760, 4761, 4762, 4763, 4764, 4765, 4801, 4802, 4803, 4804, |
|
|
|
4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, |
|
|
|
4819, 4820, 4821, 4823, 4824, 4901, 4902, 4903, 4904, 4979, |
|
|
|
] |
|
|
|