আমি এমন একটি পদ্ধতির প্রস্তাব দিচ্ছি যা কেবল জ্যামিতি জেনারেটর এবং একটি কাস্টম ফাংশনে পুনরাবৃত্তি হয়।
শুরু করার আগে, আমি নিম্নরেখাঙ্কিত করতে চাই যে আমি কাঙ্ক্ষিত ফলাফল পুনরুত্পাদন করার জন্য ন্যূনতম জিনিসগুলির ব্যাখ্যায় মনোনিবেশ করব: এর অর্থ হ'ল কিছু অন্যান্য ছোট ছোট প্যারামিটার (যেমন আকার, প্রস্থ এবং অন্যান্য) আপনার দ্বারা সহজেই সামঞ্জস্য করা উচিত আপনার প্রয়োজন আরও ভাল ফিট করার জন্য।
অতএব, এই সমাধানটি ভৌগলিক এবং প্রস্তাবিত রেফারেন্স সিস্টেমগুলির জন্য উভয়ই কাজ করে: নিম্নলিখিতটিতে আমি অনুমান করা সিআরএস (অর্থাত্ পরিমাপের ইউনিটগুলি মিটার) ব্যবহার করার কথা ধরেছিলাম, তবে আপনি আপনার সিআরএস অনুসারে এগুলি পরিবর্তন করতে পারবেন।
প্রসঙ্গ
আসুন ধরে নেওয়া যাক এই লাস্টারিং ভেক্টর স্তরটি তারগুলি উপস্থাপন করে (লেবেলগুলি ওভারল্যাপিং (কাকতালীয়) তারের সংখ্যাকে উপস্থাপন করে):
সমাধান
প্রথমে, যান 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