2012-05-15 4 views
2

작은 실험을 위해 XML에서 Prolog로 내 보낸 OSM 데이터 세트를 변환하고 싶습니다.OSM 데이터를 Prolog 사실로 변환 하시겠습니까?

특정 범용 XML 대 프롤로그 변환기 (예 : Pl4Xml)가 있지만 이러한 일반 용도 변환기가이 문제를 해결하는 가장 좋은 방법입니까? 아마도 누군가가 OSM 데이터를 Prolog에서 표현하도록 변환하는 라이브러리에 대해 알고 있습니까?

답변

2

세르지오, 나는 최선의 방법을 모른다. 그러나 나는 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 가지의 다른 태그 키를 가지고있다. 제대로 처리해야합니다. 가장 좋은 방법은 공통적 인 tags 구성원과 OSM 노드, 방법 및 관계에 대한 술어를 사용하고 태그 데이터를 정렬 된 키 - 값 쌍 (또는 AVL 트리) 집합으로 나타내는 것입니다. 나는 Uranium Test의 개발자이기 때문에 Uranium이 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 클래스를 정의 -이 (추가 술어의 도움으로) 값라는 이름의 접근 가능성을 가진 보통의 프롤로그 용어 및 상속, 객체 데이터베이스 등과 같은 많은 것들이 있습니다.이 모듈은 element_v의 자식 인 node_v, way_vrelation_v (_v는 객체의 접미사 임)을 정의합니다. element_v에는 각각 tags 필드가 있습니다.

barrier_v은 태그 키 (또는 값)를 기반으로 OSM 클래스를 인식하는 방법의 예입니다. 이 예에서 'element_v?'/ 3이라는 특수 술어는 객체의 클래스를 계산합니다. barrier_v는 node_v 또는 way_v의 하위 항목이 될 수 있습니다 (이 예제에서는 표시되지 않음).

모듈의 마지막 부분은 XML (콜백) 구문 분석기입니다. ~ 1.7G 파일로 테스트했는데 잘 작동합니다 (SWI-Prolog).

노드 - 표준 프롤로그 데이터베이스를 기반으로하는 객체 DB입니다 (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 
) 

은 우라늄 개체 많이 제공/DB 조작 조건, 그래프 algorithmes 다른 많은 생각한다. 이 모든 것을 프로젝트 웹 사이트에 표시하지 않아서 죄송합니다. 우리는 상업 프로젝트에서 주로 우라늄을 사용하고 SF 사이트는 자유 시간의 자녀입니다. 그러나 그것은 오픈 소스이며 우리는 공유 할 문서와 예제가 많이 있습니다.

내 대답이 유용하길 바랍니다.

관련 문제