কিউজিআইএস-এ ওভারল্যাপিং লাইনের প্রদর্শন স্থানান্তর?


10

যখন পয়েন্টগুলি ওভারল্যাপিং হয়, তখন এই সম্পত্তিটি থাকে যেখানে তারা যেখানে থাকে তার চারপাশে আলাদাভাবে তাদের প্রচুর পরিমাণে আলাদাভাবে প্রদর্শন করতে দেয়, যাকে বলা হয় 'পয়েন্ট স্থানচ্যুতি'। তবে এটি লাইনের জন্য কাজ করে না, তবুও এ জাতীয় কিছু অর্জনের জন্য এটি আমার কাছে যথেষ্ট ধারণামূলকভাবে সম্ভব বলে মনে হয়:

এখানে চিত্র বর্ণনা লিখুন

আমার একেবারে ভিন্ন ভিন্ন লাইনগুলি দেখতে হবে যা বাস্তবে একই স্থানে রয়েছে (আমি টেলিকমিউনিকেশন নেটওয়ার্কিংয়ে কাজ করছি)। আমি এখন দেখার একমাত্র উপায় হ'ল উপরের ছবিটির মতো সত্যই বিভিন্ন লাইন তৈরি করা, এভাবে স্থানগত ভুল তৈরি করা।

আমি কিউজিআইএস 2.14 ব্যবহার করছি।


আমি মনে করি স্টাইলিং এর সাথে পুনরাবৃত্তি করে কিছু করা যেতে পারে। মাঝখানে রেখাটি কি শুরু রেখা? তারপরে, আমি দেখতে পাচ্ছি যে আপনি তিনটি পৃথক পৃথক জ্যামিতি ব্যবহার করে অন্য প্রতিটি লাইন তৈরি করেছেন, সুতরাং আমার প্রশ্নটি যদি তাদের রেন্ডারিং থেকে কিছু নির্দিষ্ট অতিরিক্ত নিয়ম থাকে?
এমগ্রি

@ এমগ্রি আমি আপনার প্রশ্নটি বোঝার ব্যাপারে নিশ্চিত নই। প্রদত্ত ছবিটি একটি উদাহরণ যেখানে আমি বিক্ষোভের জন্য পাঁচটি ভিন্ন লাইন আঁকলাম। বাস্তবে এটি আরও বেশি হবে যে এই 5 টি লাইন প্রকৃতপক্ষে মাঝের জায়গার জায়গাতেই রয়েছে (তারা তারে রয়েছে, সুতরাং সমস্ত একই পাতায় আটকে রয়েছে)।
গুইম ক্লেয়ার

1
আপনি একটি স্থানচ্যুতি ("অফসেট") এর সাথে লাইনগুলিও রেন্ডার করতে পারেন, তবে তারা শুরু এবং শেষ পয়েন্টগুলিতে মিলবে না।
আন্দ্রেজে

@ আন্ড্রেজে হ্যাঁ, এবং অন্য একটি সমস্যা হ'ল এটি হ'ল ম্যানুয়াল অপারেশন যেখানে আমার আরও কিছু স্বয়ংক্রিয় প্রয়োজন হবে কারণ এটি অনেক ব্যবহারকারী ব্যবহার করবেন।
গুইম ক্লেয়ার

1
@ গুইওমক্লেয়ার সংযুক্ত চিত্রটি অনুসরণ করার পরে, আমি ধরে নিয়েছি যে আপনি একটি লাইন থেকে শুরু করেন যা অন্য চারটি লাইনকে ওভারল্যাপ করে and আমি কেবল বলেছি যে নতুন জ্যামিতি তৈরি করার প্রয়োজন ছাড়াই সংযুক্ত চিত্রটিতে যা প্রদর্শিত হয় তা পুনরুত্পাদন করা সম্ভব (তবে কেবল প্রারম্ভিক স্তরটির শৈলীর বৈশিষ্ট্যে পুনরাবৃত্তি)। আরেকটি উপায় হ'ল আন্দ্রেজে প্রস্তাবিত একটি উপায়, তবে মনে হয় এটি আপনার প্রয়োজনের সাথে খাপ খায় না।
এমগ্রি

উত্তর:


12

আমি এমন একটি পদ্ধতির প্রস্তাব দিচ্ছি যা কেবল জ্যামিতি জেনারেটর এবং একটি কাস্টম ফাংশনে পুনরাবৃত্তি হয়।

শুরু করার আগে, আমি নিম্নরেখাঙ্কিত করতে চাই যে আমি কাঙ্ক্ষিত ফলাফল পুনরুত্পাদন করার জন্য ন্যূনতম জিনিসগুলির ব্যাখ্যায় মনোনিবেশ করব: এর অর্থ হ'ল কিছু অন্যান্য ছোট ছোট প্যারামিটার (যেমন আকার, প্রস্থ এবং অন্যান্য) আপনার দ্বারা সহজেই সামঞ্জস্য করা উচিত আপনার প্রয়োজন আরও ভাল ফিট করার জন্য।

অতএব, এই সমাধানটি ভৌগলিক এবং প্রস্তাবিত রেফারেন্স সিস্টেমগুলির জন্য উভয়ই কাজ করে: নিম্নলিখিতটিতে আমি অনুমান করা সিআরএস (অর্থাত্ পরিমাপের ইউনিটগুলি মিটার) ব্যবহার করার কথা ধরেছিলাম, তবে আপনি আপনার সিআরএস অনুসারে এগুলি পরিবর্তন করতে পারবেন।


প্রসঙ্গ

আসুন ধরে নেওয়া যাক এই লাস্টারিং ভেক্টর স্তরটি তারগুলি উপস্থাপন করে (লেবেলগুলি ওভারল্যাপিং (কাকতালীয়) তারের সংখ্যাকে উপস্থাপন করে):

এখানে চিত্র বর্ণনা লিখুন


সমাধান

প্রথমে, যান Layer Properties | Styleএবং তারপরে Single symbolরেন্ডার বেছে নিন ।

Symbol selectorকথোপকথন থেকে Geometry generatorপ্রতীক স্তর স্তর এবং Linestring / MultiLinestringজ্যামিতির ধরণ হিসাবে একটি চয়ন করুন । তারপরে, Function Editorট্যাবে ক্লিক করুন :

এখানে চিত্র বর্ণনা লিখুন

তারপরে, ক্লিক করুন New fileএবং draw_wiresনতুন ফাংশনের নাম লিখুন :

এখানে চিত্র বর্ণনা লিখুন

আপনি দেখতে পাবেন যে একটি নতুন ফাংশন তৈরি করা হয়েছে এবং এটি ডায়ালগের বাম দিকে তালিকাভুক্ত রয়েছে। এখন, ফাংশনটির নামটিতে ক্লিক করুন এবং @qgsfunctionনিম্নলিখিত কোডটি দিয়ে ডিফল্টটি প্রতিস্থাপন করুন (এখানে সংযুক্ত সমস্ত লাইব্রেরি যুক্ত করতে ভুলবেন না):

from qgis.core import *
from qgis.gui import *
from math import sin, cos, radians

@qgsfunction(args='auto', group='Custom')
def draw_wires(angle, percentage, curr_feat, layer_name, feature, parent):

    def wires(polyline, new_angle, percentage):
        for x in range(0, len(polyline)-1):
            vertices = []
            first_point = polyline[x]
            second_point = polyline[x +1]
            seg = QgsGeometry.fromPolyline([first_point, second_point])
            len_feat = seg.length()
            frac_len = percentage * len_feat
            limb = frac_len/cos(radians(new_angle))
            tmp_azim = first_point.azimuth(second_point)
            angle_1 = radians(90 - (tmp_azim+new_angle))
            dist_x, dist_y = (limb * cos(angle_1), limb * sin(angle_1))
            point_1 = QgsPoint(first_point[0] + dist_x, first_point[1] + dist_y)
            angle_2 = radians(90 - (tmp_azim-new_angle))
            dist_x, dist_y = (limb * cos(angle_2), limb * sin(angle_2))
            point_2 = QgsPoint(second_point[0] - dist_x, second_point[1] - dist_y)
            tmp_azim = second_point.azimuth(first_point)
            angle_3 = radians(90 - (tmp_azim+new_angle))
            dist_x, dist_y = (limb * cos(angle_3), limb * sin(angle_3))
            point_3 = QgsPoint(second_point[0] + dist_x, second_point[1] + dist_y)
            angle_4 = radians(90 - (tmp_azim-new_angle))
            dist_x, dist_y = (limb * cos(angle_4), limb * sin(angle_4))
            point_4 = QgsPoint(first_point[0] - dist_x, first_point[1] - dist_y)
            vertices.extend([first_point, point_1, point_2, second_point, point_3, point_4, first_point])
            tempGeom = QgsGeometry.fromPolyline(vertices)
            num.append(tempGeom)
        return num


    layer = QgsMapLayerRegistry.instance().mapLayersByName(layer_name)[0]

    all_feats = {}
    index = QgsSpatialIndex()
    for ft in layer.getFeatures():
        index.insertFeature(ft)
        all_feats[ft.id()] = ft

    first = True

    tmp_geom = curr_feat.geometry()
    polyline = tmp_geom.asPolyline()
    idsList = index.intersects(tmp_geom.boundingBox())
    occurrences = 0
    for id in idsList:
        test_feat = all_feats[id]
        test_geom = test_feat.geometry()
        if tmp_geom.equals(test_geom):
            occurrences += 1
    if occurrences & 0x1:
        num = [tmp_geom]
    else:
        num = []

    rapp = occurrences/2
    i=2
    new_angle = angle

    while i <= occurrences:
        draw=wires(polyline, new_angle, percentage)
        i += 2
        new_angle -= new_angle/rapp
    first = True
    for h in num:
        if first:
            geom = QgsGeometry(h)
            first = False
        else:
            geom = geom.combine(h)
    return geom

এটি হয়ে গেলে, Loadবোতামটিতে ক্লিক করুন এবং আপনি ডায়ালগের Customমেনু থেকে ফাংশনটি দেখতে পাবেন Expression

এখন, এই ভাবটি টাইপ করুন (নীচের চিত্রটি একটি রেফারেন্স হিসাবে দেখুন):

draw_wires(40, 0.3, $currentfeature, @layer_name)

এখানে চিত্র বর্ণনা লিখুন

আপনি কেবল একটি ফাংশন পরিচালনা করেছেন যা বলছে, কাল্পনিক উপায়ে:

"বর্তমান স্তর ( @ লেয়ার_নাম ) এবং বর্তমান বৈশিষ্ট্য ( $ কারেন্ট ফিচার ) এর জন্য, প্রাথমিক সর্বাধিক 40 ডিগ্রি খোলার ব্যবহার করে এবং বর্তমান বিভাগের দৈর্ঘ্যের 0.3 গুন দূরত্বে দিক পরিবর্তন করে তারগুলি একসাথে প্রদর্শন করুন।"

আপনাকে কেবল দুটি জিনিস পরিবর্তন করতে হবে যা আপনি চান প্রথম দুটি প্যারামিটারের মান, তবে অবশ্যই যুক্তিসঙ্গত উপায়ে (প্রদত্ত হিসাবে অন্যান্য ফাংশন প্যারামিটারগুলি রেখে দিন)।

পরিশেষে, Applyপরিবর্তনগুলি প্রয়োগ করার জন্য বোতামটিতে ক্লিক করুন ।

আপনি এরকম কিছু দেখতে পাবেন:

এখানে চিত্র বর্ণনা লিখুন

প্রত্যাশিত.


সম্পাদনা

একটি মন্তব্যে ওপি কর্তৃক উত্থিত একটি নির্দিষ্ট অনুরোধ অনুসারে:

"প্রতিটি পর্বরেখার পরিবর্তে প্রতিটি পললাইনটির শুরু এবং শেষের মধ্যে এই প্যাটার্নটি তৈরি করা সম্ভব হবে কি?"

আমি কোডটি কিছুটা সম্পাদনা করেছি। নিম্নলিখিত ফাংশনটি প্রত্যাশিত ফলাফলটি ফিরিয়ে আনবে:

from qgis.core import *
from qgis.gui import *
from math import sin, cos, radians

@qgsfunction(args='auto', group='Custom')
def draw_wires(angle, percentage, curr_feat, layer_name, feature, parent):

    def wires(polyline, new_angle, percentage):
        vertices = []
        len_feat = polyline.length()
        frac_len = percentage * len_feat
        limb = frac_len/cos(radians(new_angle))
        tmp_azim = first_point.azimuth(second_point)
        angle_1 = radians(90 - (tmp_azim+new_angle))
        dist_x, dist_y = (limb * cos(angle_1), limb * sin(angle_1))
        point_1 = QgsPoint(first_point[0] + dist_x, first_point[1] + dist_y)
        angle_2 = radians(90 - (tmp_azim-new_angle))
        dist_x, dist_y = (limb * cos(angle_2), limb * sin(angle_2))
        point_2 = QgsPoint(second_point[0] - dist_x, second_point[1] - dist_y)
        tmp_azim = second_point.azimuth(first_point)
        angle_3 = radians(90 - (tmp_azim+new_angle))
        dist_x, dist_y = (limb * cos(angle_3), limb * sin(angle_3))
        point_3 = QgsPoint(second_point[0] + dist_x, second_point[1] + dist_y)
        angle_4 = radians(90 - (tmp_azim-new_angle))
        dist_x, dist_y = (limb * cos(angle_4), limb * sin(angle_4))
        point_4 = QgsPoint(first_point[0] - dist_x, first_point[1] - dist_y)
        vertices.extend([first_point, point_1, point_2, second_point, point_3, point_4, first_point])
        tempGeom = QgsGeometry.fromPolyline(vertices)
        num.append(tempGeom)

    layer = QgsMapLayerRegistry.instance().mapLayersByName(layer_name)[0]

    all_feats = {}
    index = QgsSpatialIndex()
    for ft in layer.getFeatures():
        index.insertFeature(ft)
        all_feats[ft.id()] = ft
    first = True
    tmp_geom = curr_feat.geometry()
    coords = tmp_geom.asMultiPolyline()
    if coords:
        new_coords = [QgsPoint(x, y) for x, y in z for z in coords]
    else:
        coords = tmp_geom.asPolyline()
        new_coords = [QgsPoint(x, y) for x, y in coords]
    first_point = new_coords[0]
    second_point = new_coords[-1]
    polyline=QgsGeometry.fromPolyline([first_point, second_point])
    idsList = index.intersects(tmp_geom.boundingBox())
    occurrences = 0
    for id in idsList:
        test_feat = all_feats[id]
        test_geom = test_feat.geometry()
        if tmp_geom.equals(test_geom):
            occurrences += 1
    if occurrences & 0x1:
        num = [polyline]
    else:
        num = []

    rapp = occurrences/2
    i=2
    new_angle = angle

    while i <= occurrences:
        draw=wires(polyline, new_angle, percentage)
        i += 2
        new_angle -= new_angle/rapp
    first = True
    for h in num:
        if first:
            geom = QgsGeometry(h)
            first = False
        else:
            geom = geom.combine(h)
    return geom

কি দারুন! এটি একটি চিত্তাকর্ষক উত্তর! এই সময়টি এটি খুঁজে পেতে এবং ভাগ করে নেওয়ার জন্য আপনাকে অনেক ধন্যবাদ। তবে: ১. এটি আমার ডেটাতে প্রয়োগ করতে আমার সমস্যা হচ্ছে (যখন আমি ফাংশনটি প্রয়োগ করি তখন লাইনগুলি অদৃশ্য হয়ে যায়), তবে আমার ধারণা সমস্যাটি আমার ডেটাগুলি থেকে এসেছে কারণ এটি একটি অস্থায়ী স্তরের উপর কাজ করে এবং ২. এটি তৈরি করা কি সম্ভব হবে? এই প্যাটার্নটি প্রতিটি উল্লম্বের পরিবর্তে প্রতিটি পললাইনটির শুরু এবং শেষের মধ্যে?
গুইম ক্লেয়ার

@ গুইঅ্যাম ক্লেয়ার লাইনগুলি অদৃশ্য হয়ে গেছে কারণ ফাংশনটিতে কিছু ভুল হয়েছে। সমস্যাটি অস্থায়ী স্তর ব্যবহার থেকে আসে না তবে এটি লাইন জ্যামিতির পরিবর্তে মাল্টলাইন জ্যামিতি ব্যবহারের সাথে সম্পর্কিত হতে পারে। দয়া করে কিউজিআইএস-এ স্তরটি লোড করুন এবং তারপরে পাইথন কনসোলে এই দুটি লাইন টাইপ করুন: layer=iface.activeLayer()এবং তারপরে print layer.wkbType()। ক্লিক করুন Run: মুদ্রিত সংখ্যার মান কোনটি?
এমগ্রি

সংখ্যাটি 5 (এটির অর্থ কী?)
গুইওম ক্লেয়ার

@ গুইওমক্লেয়ার এর অর্থ হ'ল আপনার স্তরটি একাধিক লাইনের স্ট্রিং স্তর, যখন আমি ধরে নিয়েছিলাম এটি একটি লাইনস্ট্রিং স্তর (যেহেতু আপনি এটি নির্দিষ্ট করেননি)। এটি কোনও সমস্যা হবেনা এবং যত তাড়াতাড়ি সম্ভব কোডটি সঠিকভাবে সম্পাদনা করব (সম্ভবত আগামীকাল)। তদতিরিক্ত, আমার প্রতিটি (বহু) লাইন বৈশিষ্ট্যের প্রথম এবং শেষ পয়েন্টের মধ্যে কেবল তারগুলি রেন্ডার করতে সক্ষম হওয়া উচিত।
মিগ্রি

1
হ্যাঁ, বৈশিষ্ট্যগুলি সরলরেখাগুলি (যেহেতু এগুলি পরিচালনা এবং রফতানি করা সহজতর) তাই তারের আসল দৈর্ঘ্য বিবেচনা করা ভাল।
গুইম ক্লেয়ার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.