
يعد العمل مع البيانات الجغرافية المكانية وخرائط التعيين جزءًا لا يتجزأ من العديد من تطبيقات الأعمال. يمكن أن تكون أنظمة معلومات عن المدينة والإقليم ، تطبيقات لصناعة النفط والغاز ، أنظمة إدارة البنية التحتية للنقل ، بالإضافة إلى خدمات التوصيل وغيرها. في CUBA Platform الخاصة بنا ، لإنشاء مثل هذه التطبيقات ، بالإضافة إلى الميزات الأساسية المتوفرة خارج الصندوق ، توجد مجموعة واسعة من المكونات الإضافية والمكونات . أحدها هو الرسوم البيانية والخرائط ، والتي ، بالإضافة إلى عرض الرسوم البيانية ، تتيح لك دمج خرائط جوجل في الجزء المرئي من التطبيق. في العام الماضي ، قامت Google بتحديث شروط استخدام خدمات الخرائط الخاصة بها ، مما أدى إلى زيادة في التكلفة ، كما قدمت شرط التواجد الإلزامي لملف تعريف الدفع لاستخدام واجهة برمجة التطبيقات. دفعت هذه الظروف معظم عملائنا إلى التفكير في موفري البطاقات البديلة ، وقد طُلب منا تطوير مكون بطاقة جديد.
يسعدنا الآن تقديم مكون جديد تمامًا - خرائط CUBA . تكمل خرائط CUBA وظائف التطبيق بتمثيل مرئي وأدوات بديهية لتحرير البيانات الجغرافية المكانية. يعمل المكون مع كل من البيانات النقطية والمتجهة. يمكنك استخدام أي موفر خرائط متوافق مع بروتوكول Web Map Service أو توفير مربعات بتنسيق XYZ كبيانات نقطية. للعمل مع البيانات المتجهة ، يستخدم المكون أنواع البيانات الهندسية (النقطة ، الخطوط المتعددة ، المضلع) من مكتبة JTS Topology Suite (JTS) - مكتبة Java الأكثر شعبية للعمل مع البيانات الجغرافية المكانية. يوفر المكون جميع الأدوات اللازمة لإنشاء نظام معلومات جغرافية شامل يعتمد على CUBA.
في هذه المقالة ، سوف نتحدث عن الميزات الجديدة التي يوفرها مكون الخرائط ، وكذلك مقارنتها مع مكون الخريطة السابق.
هيكل طبقة القائمة
يدعم المكون البنية التقليدية متعددة الطبقات المستخدمة على نطاق واسع في أنظمة المعلومات الجغرافية المهنية. تنقسم الطبقات بشكل أساسي إلى خطوط المسح والمتجهات. تتكون طبقات البيانات النقطية من صور نقطية ، بينما تحتوي طبقات الخطوط المتجهة على أشكال هندسية متجهة.
يدعم المكون الأنواع التالية من الطبقات:
- تعرض طبقة التجانب البلاط الذي توفره خدمات البلاط بتنسيق XYZ.
- تعرض طبقة خدمة خرائط الويب (WMS) الصور التي توفرها خدمات WMS.
- تحتوي طبقة المتجهات على كائنات جغرافية (كيانات لها سمات هندسية).
هذه الطبقات هي عناصر هيكلية للخرائط. على سبيل المثال ، قد تكون الطبقة السفلية خريطة أساسية تتكون من مربعات ، وقد تحتوي الطبقة الثانية على مضلعات تصف الوحدات الإقليمية ، على سبيل المثال ، المناطق ، وقد تحتوي الطبقة العليا على نقاط جغرافية (موقع العملاء ، المتاجر ، إلخ). بتركيب هذه الطبقات فوق بعضها البعض ، نحصل على الخريطة النهائية:

بفضل هذا النهج ، يمكنك إنشاء خرائط منظمة بوضوح مع أي محتوى.
توفر خرائط CUBA مكونًا مرئيًا جديدًا - GeoMap
. في واصف XML المكون ، يمكنك ضبط المعلمات الأساسية للخريطة ، وكذلك مجموعة من الطبقات المعروضة. مثال على مثل هذا التكوين:
<maps:geoMap id="map" height="600px" width="100%" center="37.615, 55.752" zoom="10"> <maps:layers selectedLayer="addressLayer"> <maps:tile id="tiles" tileProvider="maps_OpenStreetMap"/> <maps:vector id="territoryLayer" dataContainer="territoryDc"/> <maps:vector id="addressLayer" dataContainer="addressDc" editable="true"/> </maps:layers> </maps:geoMap>
يتيح لك هذا النهج تحقيق المزيد من المرونة التي كانت تفتقر إليها المخططات والخرائط :
- طبقات. تسمح لك هذه البنية ببناء البطاقات مع أي محتوى ، على سبيل المثال ، الجمع بين البلاط الذي توفره الخدمات المختلفة.
- توفر الطبقات تجريدًا يجمع الكائنات المتجانسة. في مكون المخططات والخرائط ، تم إلقاء جميع محتويات الخريطة (على سبيل المثال ، النقاط والمضلعات وما إلى ذلك) في كومة شائعة في مكون واجهة المستخدم. من أجل هيكلة هذه الكائنات بطريقة ما ، كان على فرق المشروع كتابة منطق إضافي.
- طريقة تعريف لوصف الطبقات. كما هو موضح في المثال أعلاه ، يمكنك تحديد بنية الخريطة بالكامل (مجموعة الطبقات) في واصف XML. في كثير من الحالات ، يكون هذا كافيًا لعدم تنفيذ أي منطق إضافي في وحدة تحكم الشاشة. باستخدام المخططات والخرائط ، كان من شبه المستحيل القيام بذلك دون كتابة منطق إضافي.
يتيح لك استخدام طبقات التجانب أو WMS العمل مع أي مزود خرائط مفضل. أنت غير مرتبط بمزود معين ، كما كان في الخرائط والرسوم البيانية .
تعمل طبقات المتجهات على تبسيط العرض والتحرير التفاعلي ورسم الكائنات الجغرافية على الخريطة.
تجدر الإشارة أيضًا إلى أن المكون المرئي لـ GeoMap
افتراضيًا يحتوي على طبقة مساعدة خاصة - قماش . يوفر Canvas واجهة برمجة تطبيقات ملائمة لعرض ورسم الأشكال الهندسية (النقاط ، الخطوط المتعددة ، المضلعات) على الخريطة. سوف نغطي أمثلة على استخدام Canvas لاحقًا في المقالة.
الكائنات الجغرافية
لنفترض أن لدينا كيانًا يحتوي على سمة مرتبطة بالهندسة (نقطة ، متعدد الخطوط ، مضلع). سوف نسمي هذا الكيان كائن جغرافي . لذلك ، يقوم المكون بتبسيط العمل مع الكائنات الجغرافية إلى حد كبير.
على سبيل المثال ، ضع في الاعتبار عنوان الكائن الجغرافي:
@Entity public class Address extends StandardEntity { ... @Column(name = "LOCATION") @Geometry @MetaProperty(datatype = "GeoPoint") @Convert(converter = CubaPointWKTConverter.class) protected Point location; ... }
يحتوي على سمة location
من النوع org.locationtech.jts.geom.Point
من org.locationtech.jts.geom.Point
JTS Topology Suite (JTS). يدعم المكون الأنواع الهندسية التالية من JTS:
org.locationtech.jts.geom.Point
- الفترة.org.locationtech.jts.geom.LineString
- متعدد الخطوط.org.locationtech.jts.geom.Polygon
- المضلع.
يتم @Geometry
سمة location
بعلامة توضيحية @Geometry
. يعلن هذا التعليق التوضيحي أنه يجب استخدام قيمة هذه السمة عند عرض كائن جغرافي على الخريطة. يتم تمييز السمة أيضًا بالتعليقات التوضيحية التالية:
@MetaProperty
- في هذه الحالة ، يستخدم للإشارة إلى سمة نوع البيانات . Datatype
استخدام واجهة Datatype
بواسطة إطار عمل CUBA لتحويل القيم من وإلى سلسلة.@Convert
- يحدد محول JPA لسمة دائمة. يحول محول JPA قيم السمات بين تمثيلاته في قاعدة البيانات ورمز Java. يوفر المكون مجموعة من أنواع البيانات المكانية ومحولات JPA. يتوفر مزيد من المعلومات في وثائق المكون. يمكنك أيضًا استخدام تطبيقك الخاص لمحول JPA ، والذي يجعل من الممكن العمل مع مصادر مختلفة للبيانات المكانية (على سبيل المثال ، PostGIS ).
وبالتالي ، من أجل تحويل كيان إلى كائن جغرافي ، تحتاج إلى تحديد سمة من النوع الهندسي JTS @Geometry
باستخدام @Geometry
. هناك خيار آخر - إنشاء سمة غير دائمة من خلال توفير أساليب getter / setter. قد يكون ذلك مفيدًا إذا كنت لا تريد إجراء تغييرات على نموذج البيانات وإعادة إنشاء البرامج النصية لـ DDL.
على سبيل المثال ، ضع في الاعتبار عنوان الكيان مع سمات منفصلة لخطوط الطول والعرض:
import com.haulmont.addon.maps.gis.utils.GeometryUtils; ... @Entity public class Address extends StandardEntity { ... @Column(name = "LATITUDE") protected Double latitude; @Column(name = "LONGITUDE") protected Double longitude; ... @Geometry @MetaProperty(datatype = "GeoPoint", related = {"latitude", "longitude"}) public Point getLocation() { if (getLatitude() == null || getLongitude() == null) { return null; } return GeometryUtils.createPoint(getLongitude(), getLatitude()); } @Geometry @MetaProperty(datatype = "GeoPoint") public void setLocation(Point point) { Point prevValue = getLocation(); if (point == null) { setLatitude(null); setLongitude(null); } else { setLatitude(point.getY()); setLongitude(point.getX()); } propertyChanged("location", prevValue, point); } ... }
إذا قررت استخدام هذا النهج ، فتأكد من استدعاء الأسلوب propertyChanged
في أداة الضبط ، حيث يستجيب المكون لهذا الحدث عن طريق تحديث الشكل الهندسي على الخريطة.
الآن وقد أعددنا فئة كائننا الجغرافي ، يمكننا إضافة مثيلات من هذه الفئة إلى طبقة المتجهات. تعد طبقة المتجه عنصر ربط بين البيانات (الكائنات الجغرافية) والخريطة. لتوصيل كائنات جغرافية بطبقة ما ، تحتاج إلى نقل حاوية البيانات أو ، في حالة الشاشات المتقادمة (حتى الإصدار 7 من CUBA) ، مصدر البيانات بطبقة المتجه. يمكن القيام بذلك باستخدام واصف XML:
<maps:geoMap id="map"> <maps:layers> ... <maps:vector id="addressesLayer" dataContainer="addressesDc"/> </maps:layers> </maps:geoMap>
نتيجة لذلك ، سيتم عرض مثيلات فئة Address
الموجودة في الحاوية addressDc على الخريطة.
دعنا نفكر في مهمة أولية: إنشاء شاشة لتحرير كائن جغرافي مع خريطة ، حيث يمكنك تحرير الشكل الهندسي للكائن. لحل المشكلة ، تحتاج إلى الإعلان عن المكون المرئي لـ GeoMap
في واصف XML لشاشة التحرير وإضافة طبقة متجهة مرتبطة بالحاوية التي تحتوي على الكائن الجغرافي المحرر:
<maps:geoMap id="map" height="600px" width="100%" center="37.615, 55.752" zoom="10"> <maps:layers selectedLayer="addressLayer"> <maps:tile ..."/> <maps:vector id="addressLayer" dataContainer="addressDc" editable="true"/> </maps:layers> </maps:geoMap>
إذا قمت بتمييز طبقة المتجه على أنه قابل للتحرير ، فسيتم تنشيط التحرير التفاعلي للكائن الجغرافي على الخريطة. إذا كانت هندسة الكائن فارغة ، فستتحول الخريطة تلقائيًا إلى وضع الرسم. كما ترى ، لحل المشكلة ، يكفي إعلان طبقة متجه على الخريطة وتمريرها / حاوية مصدر البيانات.
هذا كل شيء. إذا استخدمنا الرسوم البيانية والخرائط لحل نفس المشكلة ، فسنضطر إلى كتابة الكثير من التعليمات البرمجية في وحدة تحكم الشاشة لتوفير وظائف مماثلة. باستخدام المكون الجديد للخرائط ، أصبح حل هذه المشكلات أكثر بساطة.
قماش
هناك أوقات تحتاج فيها إلى العمل وليس مع الكيانات. بدلاً من ذلك ، تريد واجهة برمجة تطبيقات بسيطة لإضافة ورسم الأشكال الهندسية على الخريطة ، كما كان في الرسوم البيانية والخرائط . لهذا الغرض ، GeoMap
المكون المرئي GeoMap
على طبقة خاصة - قماش . هذه طبقة مساعدة ، والتي هي على الخريطة بشكل افتراضي والتي توفر واجهة برمجة تطبيقات بسيطة لإضافة ورسم الأشكال الهندسية على الخريطة. يمكنك map.getCanvas()
خريطة map.getCanvas()
عن طريق استدعاء الأسلوب map.getCanvas()
.
بعد ذلك ، سننظر في بعض المهام البسيطة ، وكيف تم حلها في الرسوم البيانية والخرائط ، وكيف تفعل الشيء نفسه باستخدام Canvas.
عرض الأشكال الهندسية على الخريطة
في المخططات والخرائط ، تم إنشاء كائنات هندسية باستخدام المكون المرئي للخريطة ، واستخدامها كمصنع ، ثم إضافتها إلى الخريطة:
Marker marker = map.createMarker(); GeoPoint position = map.createGeoPoint(lat, lon); marker.setPosition(position); map.addMarker(marker);
يعمل مكون Maps الجديد مباشرة مع فصول من مكتبة JTS:
CanvasLayer canvasLayer = map.getCanvas(); Point point = address.getLocation(); canvasLayer.addPoint(point);
تحرير الهندسة
في المخططات والخرائط ، يمكنك تعيين هندسة قابلة للتحرير. عندما تم تغيير هذه الأشكال الهندسية من خلال واجهة المستخدم ، كانت تسمى الأحداث المقابلة:
Marker marker = map.createMarker(); GeoPoint position = map.createGeoPoint(lat, lon); marker.setPosition(position); marker.setDraggable(true); map.addMarker(marker); map.addMarkerDragListener(event -> {
في مكون الخرائط ، عند إضافة هندسة JTS إلى Canvas ، تُرجع الطريقة المطابقة كائنًا خاصًا يمثل تمثيلًا لهذه الهندسة على الخريطة: CanvasLayer.Polyline
أو CanvasLayer.Polygon
أو CanvasLayer.Polygon
. يحتوي هذا الكائن على واجهة بطلاقة لإعداد العديد من معلمات الهندسة ، كما يمكن استخدامه للاشتراك في الأحداث المتعلقة بالهندسة ، أو لحذف هندسة من قماش.
CanvasLayer canvasLayer = map.getCanvas(); CanvasLayer.Point location = canvasLayer.addPoint(address.getLocation()); location.setEditable(true) .setPopupContent(address.getName()) .addModifiedListener(modifiedEvent -> address.setLocation(modifiedEvent.getGeometry()));
الرسم الهندسي
في الرسوم البيانية والخرائط الإضافية القديمة كان هناك مكون إضافي - DrawingOptions
. تم استخدامه لتفعيل القدرة على الرسم على الخريطة. بعد رسم الهندسة ، تم رفع الحدث المقابل:
DrawingOptions options = new DrawingOptions(); PolygonOptions polygonOptions = new PolygonOptions(true, true, "#993366", 0.6); ControlOptions controlOptions = new ControlOptions( Position.TOP_CENTER, Arrays.asList(OverlayType.POLYGON)); options.setEnableDrawingControl(true); options.setPolygonOptions(polygonOptions); options.setDrawingControlOptions(controlOptions); options.setInitialDrawingMode(OverlayType.POLYGON); map.setDrawingOptions(options); map.addPolygonCompleteListener(event -> {
يجعل مكون الخرائط نفس الأمر أسهل بكثير. يحتوي تطبيق Canvas Canvas الجديد على مجموعة من الأساليب لرسم الأشكال الهندسية. على سبيل المثال ، لرسم مضلع ، استخدم الأسلوب canvas.drawPolygon()
. بعد الاتصال بهذه الطريقة ، ستتحول الخريطة إلى وضع رسم المضلع. تقبل الطريقة وظيفة Consumer<CanvasLayer.Polygon>
، حيث يمكنك تنفيذ إجراءات إضافية باستخدام المضلع المرسوم.
canvasLayer.drawPolygon(polygon -> { territory.setPolygon(polygon.getGeometry()); });
أدوات التحليل الجغرافي
تجمع
هناك أداة مفيدة أخرى موجودة في مكون الخرائط الجديد وهي تجميع النقاط. إذا كانت الطبقة تتكون من عدد كبير من النقاط ، فيمكنك تمكين التجميع لتجميع النقاط القريبة في مجموعات بحيث تبدو الخريطة أفضل وأكثر إدراكًا:

يتم تمكين التجميع عن طريق إضافة علامة cluster
داخل علامة vector
في واصف XML:
<maps:vector id="locations" dataContainer="locationsDc" > <maps:cluster/> </maps:vector>
يمكنك أيضًا تمكين التجميع استنادًا إلى أوزان النقاط. وزن النقطة هو قيمة السمة المحددة في المعلمة weightProperty
.
<maps:vector id="orders" dataContainer="ordersDc" > <maps:cluster weightProperty="amount"/> </maps:vector>
خرائط الحرارة
تعتبر Heatmaps تمثيلًا مرئيًا لكثافة البيانات عبر مواقع جغرافية متعددة. يحتوي المكون المرئي لـ GeoMap على طريقة لإضافة خريطة حرارة: addHeatMap(Map<Point, Double> intensityMap)
.

استنتاج
تعد معالجة وتحليل وتصور البيانات الجغرافية المكانية عنصرا أساسيا في العديد من تطبيقات الأعمال. سيوفر مكون خرائط CUBA تطبيق CUBA الخاص بك بكل الأدوات اللازمة لتنفيذ هذه الوظيفة.
تساعد البنية المستندة إلى الطبقة في بناء الخرائط بأي محتوى. مع طبقات التجانب / WMS ، يمكنك استخدام أي مزود تحتاجه كبطاقة أساسية. تتيح لك طبقات المتجهات العمل بفعالية مع مجموعات من الكائنات الجغرافية المتجانسة. يوفر Canvas واجهة برمجة تطبيقات بسيطة لعرض ورسم الأشكال الهندسية على الخريطة.
يعمل المكون مع أنواع مكانية من مكتبة JTS ، مما يجعله متوافقًا مع العديد من الأطر الأخرى (على سبيل المثال ، GeoTools ) لحل مجموعة واسعة من المهام المتعلقة بمعالجة البيانات الجغرافية وتحليلها.
نأمل أن تستمتع المكون. في انتظار ملاحظاتك!