将OSM数据转换为Prolog事实?
对于一个小实验,我想将导出的数据集从XML转换为Prolog将OSM数据转换为Prolog事实?,prolog,converter,openstreetmap,Prolog,Converter,Openstreetmap,对于一个小实验,我想将导出的数据集从XML转换为Prolog 我知道有一些通用的XML-to-Prolog转换器(例如),但是这些通用转换器是解决这个问题的最好方法吗?可能有人知道有一个库可以将OSM数据转换成Prolog中方便的表示形式?Sergio,我不知道最好的方法。但我用OSM做了自己的小实验。我没有使用Pl4XML,只是使用带库的SWI Prolog(sgml)。像这样: tt2(tag, Attrs, _) :- memberchk(k=Key, Attrs), \+
我知道有一些通用的XML-to-Prolog转换器(例如),但是这些通用转换器是解决这个问题的最好方法吗?可能有人知道有一个库可以将OSM数据转换成Prolog中方便的表示形式?Sergio,我不知道最好的方法。但我用OSM做了自己的小实验。我没有使用Pl4XML,只是使用带库的SWI Prolog(sgml)。像这样:
tt2(tag, Attrs, _) :-
memberchk(k=Key, Attrs),
\+ tag(Key), assertz(tag(Key)),
fail ; true.
?- dynamic tag/1.
?- new_sgml_parser(Parser, []),
open('UA.osm', read, Stream),
sgml_parse(Parser, [source(Stream), call(begin, tt2)]),
free_sgml_parser(Parser),
close(Stream).
UA.osm是我的XML数据。我有1000多个不同的标签键。应该妥善处理。我认为最好的方法是对OSM节点、方式和与公共标记成员的关系使用谓词,并将标记数据表示为一组有序的键值对(或AVL树)。因为我是的开发者,我认为铀为我提供了最好的Prolog对象模型(对于特定的Prolog实现没有锁定)。我可以给您举一个如何管理OSM对象关系的示例:
:- module(node_v, [on_begin/3, on_end/2]).
:- use_module(u(v)).
% helper for callback tag parsing
new_class(xml_tag_v, db_object_v, [closed_by_parser]).
% OSM element
new_class(element_v, xml_tag_v,
[id,
changeset,
visible,
user,
timestamp,
tags]).
% OSM node, way and barrier - children of element
new_class(node_v, element_v, [lat, lon]).
new_class(way_v, element_v, [nodes]).
new_class(barrier_v, element_v, [barrier_type]).
% Example of a tag-based dynamic class
% (see http://wiki.openstreetmap.org/wiki/Barriers)
'element_v?'(Obj, class, barrier_v) :-
obj_field(Obj, tags, Tags),
% if it contains Key:barrier it is a barrier
% (way or node)
memberchk(barrier-_, Tags), !.
% XML parsing callbacks
on_begin(node, Attrs, _) :-
% Construct the node_v object
obj_construct(node_v, [], [], Obj),
foreach(member(Name=Value, Attrs),
obj_field(Obj, weak, Name, Value)),
% Put it into DB 'nodes'
db_recorda(nodes, Obj).
on_begin(tag, Attrs, _) :-
db_recorded(nodes, Obj0), !,
obj_rewrite(Obj0,
[closed_by_parser, tags],
[Is_Closed, Tags0],
[Is_Closed, Tags], Obj),
var(Is_Closed), !, % found unclosed node
memberchk(k=Key, Attrs),
memberchk(v=Value, Attrs),
( var(Tags0) -> Tags1 = [] ; Tags1 = Tags0 ),
Tags = [Key - Value|Tags1], % add new tag
db_recorda(nodes, _, Obj, _, replaced). % db update
on_end(node, _) :-
% close the node parsing
db_recorded(nodes, Obj0), !,
obj_rewrite(Obj0,
[closed_by_parser, tags],
[_, Tags0],
[true, Tags], Obj),
( var(Tags0)
-> Tags = []
; sort(Tags0, Tags) % if your expectation for a number of tags is big
% try use library(assoc) (AVL trees)
),
db_put_object(nodes, _, Obj, _, replaced).
new_class/3定义了一个类-它是一个常用的prolog术语,可以命名访问值(借助附加谓词)和许多其他东西,如继承、对象数据库等。该模块定义了三个主要的OSM实体—节点
、方式
和关系
(\u v是对象的后缀)作为元素的子元素。每个元素都包含标记
字段
barrier\u v
是一个基于标记键(或值)识别OSM类的示例。在本例中,一个特殊的谓词'element_v?'/3计算一个对象的类。barrier_v可以是node_v或way_v的子级(本例中未显示)
模块的最后一部分是XML(回调)解析器。我用~1.7G文件对它进行了测试,效果很好(SWI-Prolog)
nodes-是一个基于标准prolog数据库的对象数据库(也可以在将来的版本中使用外部PostgreSQL)
一个解析结果的示例是:
?- db_recorded(nodes, N), obj_pretty_print(N), !.
N = node_v(70, '6176525', true, nodes, 32, '10980421', '46.4718061', '30.7308961',
[highway-traffic_signals], '2010-10-25T19:17:07Z', 'Buccaneer', _G391)
node_v (
changeset : 6176525
closed_by_parser : true
db_key : nodes
db_ref : 32
id : 10980421
lat : 46.4718061
lon : 30.7308961
tags : [highway-traffic_signals]
timestamp : 2010-10-25T19:17:07Z
user : Buccaneer
)
铀还提供了许多对象/数据库操作谓词、图形算法和许多其他思想。很抱歉没有在项目网站上显示所有这些内容。我们主要在商业项目中使用铀,SF网站是我空闲时间的产物。但是它是开源的,我们有很多文档和例子可以分享
我希望我的回答有用