
PostGIS هو برنامج مفتوح المصدر يضيف دعمًا للميزات الجغرافية لقاعدة بيانات PostgreSQL.
هذا المقال القصير سوف يناقش استخدامه في جافا. على وجه الخصوص ، مهمة العثور على الأشياء الجغرافية عن طريق إحداثياتها.
تم إنشاء PostGIS في عام 2001. إنه حل مجاني جيد لتخزين بيانات الخرائط في قاعدة البيانات. لكن المقال لا يتعلق به تمامًا ، بل يتعلق فقط بحالة خاصة - العمل المريح مع PostGIS باستخدام أدوات JPA.
التبعيات
المكتبات التالية مهمة لمهمتنا:
- السبات 5.3.7
- السبات المكاني - نفس الإصدار. نظريا ، يمكنك استخدام الأكبر سنا. ابتداءً من الخامس ، الإسبات-المكاني هو نفسه السبات. سابقًا: Hibernate Spatial 1.1.x لـ Hibernate 3.6.x ، Hibernate Spatial 1.0 لـ Hibernate 3.2.x - 3.5.x.
- postgresql 42.2.4. تم أخذ هذا الإصدار ، لأن الأحدث منها شددت متطلبات طبقة المقابس الآمنة. اختر إصدار برنامج التشغيل الذي يطابق إصدار قاعدة البيانات.
حسنًا ، كل ما تحتاجه لـ JPA هو Spring أو حاوية.
لهجات
يوفر Hibernate Spatial
التجريدات الهندسية للعمل مع القواعد المكانية. كما في JPA ، كتقريب أولي ، لسنا مهتمين بقاعدة البيانات التي يتم استخدامها على الخادم.
مدعومة رسميا من قبل PostgresSQL و Oracle و MySQL و MS SQLServer و GeoDB (H2) و DB2.
ميزات تفاصيل الدعم . قد تبدو العضلات مثل شخص غريب. ولكن في الإصدار 8 ، تم
تحسين دعم البيانات المكانية بشكل لائق.
نحن نستخدم بوستجرس. لكنك تحتاج إلى تحديد لهجة الإسبات
"org.hibernate.spatial.dialect.postgis.PostgisDialect"
بدلاً من واحدة بعد اليونانية القياسية.
حان الوقت لشفرة
يمكن أن يحتوي الجدول في PostGIS على أي حقول. مجرد معيار ، واحد منهم سيكون من نوع الهندسة. وهناك جغرافيا (غير مدعومة الآن في سبات). إذا لم تعلم Java التعامل مع هذا النوع ، فسيتم تفسيره على أنه نقطة أو سلسلة من النموذج "01010000207B7F0000188D594CC9B22541BC4E56674F2C5541".
بالطبع ، يمكنك العمل مع PostGis على JBDC خالص.
مثال ولكن هذا يتطلب عملاً مضنياً منفصلاً مع
org.postgis.PGgeometry
. هذه ليست الفصول التي سوف تكون المقالة عنها. ولن يكون هناك تسامح بعد الآن.
نذهب إلى JPA وإنشاء فئة بسيطة:
@Entity public class AdressBuilding implements Serializable { @Id private Integer id; private Point geom; ...
تم حذف الحقول المتبقية (يمكن لأي كائن جغرافي تخزين أي معلومات). لا شيء غير عادي هنا - فئة الكيان القياسية. فقط كائن من فئة Point مثير للاهتمام - نقطة في الفضاء ثلاثي الأبعاد.
فيما يلي ، يتم استخدام فئات من حزمة com.vividsolutions.jts.geom.
أصبح JTS المعيار الفعلي لتمثيل البيانات الجغرافية المكانية. يقوم بتنفيذ مواصفات مواصفات
بسيطة /
وصول ميزة بسيطة تم إنشاؤها بواسطة OpenGIS مرة أخرى في 90s.
التوضيح . يرث نقطة من فئة الهندسة مجردة. يحتوي على الحقول غير الثابتة التالية:
protected Envelope envelope; protected final GeometryFactory factory; protected int SRID; private Object userData;
المغلف هو الحد الأدنى المربع المحيط لهذه الهندسة. ولكن يمكن أن يعود في شكل هندسة. وبعد ذلك سيكون لديك محاولة لا نهاية لها في التسلسل.
SRID - تنسيق رقم النظام. هناك الكثير منهم. الاختلافات الرئيسية: تنسيق الإحداثيات (بالأمتار ، الدرجات ...) ، النقطة المرجعية وشكل الأرض (الأرض ليست مستديرة). يعرف PostGis العديد من أنظمة التنسيق ويمكنه تحويلها.
كما قلت ، لدينا نوع هندسة في قاعدة البيانات. لقد استخدمت على الفور فئة Point الملموسة للراحة ، لأنه في هذا الجدول ، لديّ كائنات نقطة فقط. لكن نظرية PostGIS يمكنها تخزين عدة أنواع من الهندسة في وقت واحد. فقط في كل هندسة يشار إلى نوعه:
"geometry":{"type":"MultiPolygon","coordinates":...
وفقًا لـ StackOverflow ، يؤدي استخدام أشكال هندسية متعددة في نفس الجدول إلى إبطاء الاستعلامات. ويمكن أيضا أن تكون متداخلة الهندسة. أنواع:

استعلامات قاعدة البيانات
مع تنفيذ الطبقة برزت. الآن حان الوقت للحصول عليها من القاعدة. نقاطنا هي المنازل ، أو بالأحرى عناوينهم. يمكنك تقديم استعلامات SQL مألوفة: الحصول على منازل حسب المعرف ، وعدد ، وعدد الجدات ...
نحن مهتمون الآن بالاستعلامات المكانية. على سبيل المثال ، ابحث عن منزل عن طريق الإحداثيات. اجعل الإحداثيات المطلوبة x و y و + -delta هي منطقة البحث المطلوبة. يتم تنفيذ الاستعلامات الرئيسية في STS على نسبة الأشكال الهندسية. لذلك ، نحن بحاجة إلى إنشائه:
Coordinate c1 = new Coordinate(x - delta, y - delta); ... Coordinate[] coordinates = new Coordinate[]{c1, c2, c3, c4, c1}; GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
إذا لم نحدد نظام إحداثيات ، فإن PostGis سيرفض مقارنتها. أنت تعرف رمز النظام الخاص بك ، أو احصل عليه من أي مكان باستخدام الرمز
.getGeom().getSRID()
.
بعد ذلك نرسل طلب النموذج:
"select a " + "from AdressBuilding a " + "where within(a.geom, :window) = true"
الاستعلام داخل يعني التحقق مما إذا كانت الهندسة داخل أخرى. لا تشعر بالقلق إذا قال IDE الخاص بك أنه لا يمكن أن يكون هناك مثل هذا الطلب في JPA. تحول السبات المكاني إلى:
where st_within(adressbuil0_.geom, ?)=true
حيث
st_within
هو بالفعل وظيفة PostGis.
هناك عدة خيارات لكيفية الحصول على نفس النتيجة - سقطت النقطة في مربع.
contains(:window, a.geom) / intersects(a.geom, :window)...

وصف مفصل للمواصفات
هنا .
خاتمة
حصلنا على النقاط - الآن افعل ما تريد معهم.
اختبرت حالة قاعدة بيانات صغيرة على خادم به كمية كبيرة نسبيًا من ذاكرة الوصول العشوائي. إذا قمت بالتحميل إلى أقصى حد ونسي الفهارس ، فستعمل مهمة البحث في المعالج.
Postgres لديها العديد من الفهارس المختلفة.
وبعضهم يساعد بوستجيس . أظهرت الدراسة أن فقط GIST (؟) مناسب
للنقاط CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometryfield] );
ولكن في أغلب الأحيان ، عند استيراد البيانات إلى PostGis ، يتم إنشاء الفهارس تلقائيًا ...
التوضيحات والمعلومات الإضافية هي موضع ترحيب.
دليل المستخدمة:
للسبات 5للسبات 4