50 lines
3.6 KiB
Python
50 lines
3.6 KiB
Python
from pathlib import Path
|
||
out=Path(__file__).parent
|
||
parts=['''<svg xmlns="http://www.w3.org/2000/svg" width="1400" height="1050" viewBox="0 0 1400 1050"><rect width="1400" height="1050" fill="#f5f3eb"/><style>text{font-family:Arial,sans-serif;fill:#203e32}.label{font-size:17px;font-weight:600}.small{font-size:14px;fill:#627368}.note{font-size:16px}.future{fill:none;stroke:#76978d;stroke-width:2;stroke-dasharray:7 5}</style><text x="70" y="70" font-size="34" font-weight="600">SAMFORD VALLEY</text><text x="70" y="104" font-size="21">Adaptable homestead · solar and site layout</text><path d="M1290 135V65m-9 15 9-15 9 15" stroke="#203e32" fill="none" stroke-width="2"/><text x="1283" y="52" font-size="19">N</text>''']
|
||
S=19
|
||
def xy(x,y): return (70+(x+31)*S,170+(13-y)*S)
|
||
def rect(cx,cy,w,d,fill,stroke='#52614d',css=''):
|
||
x,y=xy(cx-w/2,cy+d/2); parts.append(f'<rect x="{x}" y="{y}" width="{w*S}" height="{d*S}" fill="{fill}" stroke="{stroke}" stroke-width="1.5" class="{css}"/>')
|
||
def text(x,y,t,cl='label',anchor='middle'):
|
||
xx,yy=xy(x,y); parts.append(f'<text x="{xx}" y="{yy}" text-anchor="{anchor}" class="{cl}">{t}</text>')
|
||
def line(points,color='#c9c4ad',w=15):
|
||
pts=' '.join(f'{xy(x,y)[0]},{xy(x,y)[1]}' for x,y in points); parts.append(f'<polyline points="{pts}" fill="none" stroke="{color}" stroke-width="{w}" stroke-linejoin="round"/>')
|
||
line([(1,13),(0,9),(0,7),(-3,6.2),(-7,5),(-9,1),(-10,-3),(-13,-4.6)],w=24)
|
||
line([(0,7),(4,7.6),(8,8.4),(14,8),(19,7),(20,2),(20,-4.6),(18.2,-5.7)],w=16)
|
||
rect(0,0,12,6,'#d8d0b7'); rect(0,4.2,12,2.4,'#e7deca')
|
||
rect(-14,-8.5,8,5,'#d8d0b7')
|
||
rect(-8.6,-1.8,5.2,1.6,'#c2ad89'); rect(-11.2,-3.9,1.6,5.8,'#c2ad89')
|
||
for y in [-1.38,1.30]:
|
||
for i in range(9): rect(-4.82+i*1.205,y,1.10,1.65,'#263e4b','#9aa9ac')
|
||
for y in [-10.3,-13]:
|
||
for i in range(6): rect(7.2+i*1.21,y,1.10,1.65,'#263e4b','#9aa9ac')
|
||
for cx,cy,w,d in [(11.3,-.6,7,5),(-25,-8.5,7,5),(0,-21,8,6)]:
|
||
rect(cx,cy,w,d,'none',css='future')
|
||
if cy!=-21:
|
||
for x in [cx-w/2+.3,cx+w/2-.3]:
|
||
for y in [cy-d/2+.3,cy+d/2-.3]: rect(x,y,.35,.35,'#a5aaa3')
|
||
for x,y in [(-18.95,-4),(-21.25,-4.2)]:
|
||
x1,y1=xy(x,y); parts.append(f'<circle cx="{x1}" cy="{y1}" r="{S}" fill="#345c44"/>')
|
||
for x in [17.8,21.2]:
|
||
for y in [-2.7,.6,3.9]: rect(x,y,2.35,1.25,'#718454','#a28862')
|
||
rect(18.2,-8.5,4.3,5,'#d4e4d9','#7b9b8c')
|
||
for x in [17,19.4]: rect(x,-8.5,.7,4.3,'#7a905c')
|
||
for x,y,r in [(18,-13.4,1.5),(24,-14.4,1.7),(25,-4.7,1.4)]:
|
||
xx,yy=xy(x,y); parts.append(f'<circle cx="{xx}" cy="{yy}" r="{r*S}" fill="#b8c69a" stroke="#90a076"/>')
|
||
text(0,4.0,'NORTH VERANDA · 2.4 m','small')
|
||
text(0,-4.5,'Living pavilion · 12 × 6 m')
|
||
text(0,-5.7,'18 roof PV modules','small')
|
||
text(-14,-8.4,'Sleeping')
|
||
text(-14,-9.6,'8 × 5 m','small')
|
||
text(-8.0,-.3,'Breezeway','small')
|
||
text(11.3,-.5,'Future office','small')
|
||
text(-25,-8.5,'Future guest','small')
|
||
text(0,-21,'Future workshop','small')
|
||
text(10.3,-15.5,'12 ground PV modules','small')
|
||
text(18.2,-12.5,'Greenhouse','small')
|
||
text(19.6,6,'Six raised food beds','small')
|
||
text(-20.6,-1.9,'Two rainwater tanks','small')
|
||
text(23,-17,'Mango + avocado','small')
|
||
parts.append('''<line x1="70" y1="915" x2="1330" y2="915" stroke="#c6cbbc"/><text x="70" y="953" class="note">Build now: two pavilions, breezeway, greenhouse, garden beds, tanks and solar.</text><text x="70" y="982" class="note">Dashed outlines: future additions. Concrete pier stubs at office and guest locations.</text><text x="70" y="1013" class="small">Concept layout only. Solar capacity, storage, shading and water yield require site-specific sizing. All dimensions in metres.</text></svg>''')
|
||
(out/'samford-solar-site-layout.svg').write_text(''.join(parts))
|