### PVCollada asset example with profile="PVCollada-2.0" Source: https://pvlib.github.io/pvcollada/dev_guide.html Shows the required structure for PVCollada data, which must be identified by profile="PVCollada-2.0". Includes geographic location, unit, up_axis, and an extra technique block with a software tag. ```xml 15.3 10.1 150 Z_UP Helios 3D PVsyst ``` -------------------------------- ### Convert ENU to geodetic coordinates using pyproj Source: https://pvlib.github.io/pvcollada/pvcollada_coordinate_transformation_with_diagram.html Compute WGS-84 geodetic coordinates from local ENU coordinates using a pyproj inverse pipeline with the topocentric projection. The example uses the same cube coordinates and origin. Requires pyproj and pandas. The output is printed as a Markdown table. ```python import pandas as pd import pyproj # 1. Define the origin of your local topocentric system (tangent plane) lat_0 = 35.0845 # Latitude of origin (degrees) lon_0 = -106.651 # Longitude of origin (degrees) h_0 = 1619.0 # Ellipsoidal height of origin (meters) # 2. Build an inverse PROJ pipeline conversion string # We use +inv because we are starting with topocentric coordinates and going backward pipeline_str = ( f"+proj=pipeline " f"+step +inv +proj=topocentric +lat_0={lat_0} +lon_0={lon_0} +h_0={h_0} +ellps=WGS84 " f"+step +inv +proj=cart +ellps=WGS84 " f"+step +proj=unitconvert +xy_in=rad +xy_out=deg " f"+step +proj=axisswap +order=2,1" ) # 3. Create the transformer from the pipeline definition transformer = pyproj.Transformer.from_pipeline(pipeline_str) # 4. Input topocentric local data (East, North, Up in meters) coords = pd.DataFrame( columns=['x', 'y', 'z'], data=[[1., 1., 1.], [4., 1., 1.], [1., 3., 1.], [4., 3., 1.], [1., 1., 2.], [4., 1., 2.], [1., 3., 2.], [4., 3., 2.]] ) # Translate the cube to geocoordinates # 5. Transform the coordinates # Note: The output layout matches traditional GIS structure (Longitude, Latitude, Height) lon, lat, alt = transformer.transform( coords['x'], coords['y'], coords['z']) geodetic_coords = pd.DataFrame({'lat': lat, 'lon': lon, 'alt': alt}) print('Topocentric to Geodetic coordinates using pymap3d') print(geodetic_coords.to_markdown(index=False, floatfmt=".8f")) ``` -------------------------------- ### Convert ENU to geodetic coordinates using pymap3d Source: https://pvlib.github.io/pvcollada/pvcollada_coordinate_transformation_with_diagram.html Compute WGS-84 geodetic coordinates from local ENU coordinates using pymap3d's enu2geodetic function. The example uses a cube defined in local coordinates and an origin at Albuquerque, NM (lat 35.0845, lon -106.651, alt 1619). Requires pymap3d and pandas. The output is printed as a Markdown table. ```python import pandas as pd import pymap3d as pm lat0 = 35.0845 lon0 = -106.651 alt0 = 1619.0 # Local coordinates of corners of the cube topocentric_coords = pd.DataFrame( columns=['x', 'y', 'z'], data=[[1., 1., 1.], [4., 1., 1.], [1., 3., 1.], [4., 3., 1.], [1., 1., 2.], [4., 1., 2.], [1., 3., 2.], [4., 3., 2.]] ) # Translate the cube to geocoordinates # pymap3d.enu2geodetic uses WGS-84 by default. We'll specify a datum to show how # it is done. datum = pm.Ellipsoid.from_name('wgs84') lat, lon, alt = pm.enu2geodetic(coords['y'], coords['x'], coords['z'], lat0, lon0, alt0, ell=datum) geodetic_coords = pd.DataFrame({'lat': lat, 'lon': lon, 'alt': alt}) print('Topocentric to Geodetic coordinates using pymap3d') print(geodetic_coords.to_markdown(index=False, floatfmt=".8f")) ``` -------------------------------- ### Convert geographic to ENU with pymap3d geodetic2enu Source: https://pvlib.github.io/pvcollada/pvcollada_coordinate_transformation_with_diagram.html Converts WGS-84 geographic coordinates to PVCollada ENU coordinates using pymap3d's geodetic2enu function. Requires a DataFrame with lat, lon, and alt columns, plus the ENU origin (lat0, lon0, alt0). The example uses the WGS84 ellipsoid and prints the resulting ENU coordinates as a markdown table. ```python import numpy as np import pandas as pd import pymap3d as pm geocoords = pd.DataFrame( columns=['lat', 'lon', 'alt'], data = np.array( [[35.08450901, -106.65098904, 1620.00000016], [35.08453605, -106.65098904, 1620.00000134], [35.08450901, -106.65096711, 1620.00000078], [35.08453605, -106.65096711, 1620.00000196], [35.08450901, -106.65098904, 1621.00000016], [35.08453605, -106.65098904, 1621.00000134], [35.08450901, -106.65096711, 1621.00000078], [35.08453605, -106.65096711, 1621.00000196]] ) ) # origin of ENU coordinates lat0 = 35.0845 lon0 = -106.651 alt0 = 1619.0 datum = pm.Ellipsoid.from_name('wgs84') x, y, z = pm.geodetic2enu( geocoords['lat'], geocoords['lon'], geocoords['alt'], lat0, lon0, alt0, ell=datum ) # put x, y, z into a DataFrame for convenient printing enucoords = pd.DataFrame({'x': x, 'y': y, 'z': z}) print('Geodetic to Topocentric coordinates using pymap3d') print(coords.to_markdown(index=False, floatfmt=".8f")) ``` -------------------------------- ### Extending PVCollada with custom technique Source: https://pvlib.github.io/pvcollada/dev_guide.html Shows how to extend a PVCollada file with custom elements. Adds a custom technique with a unique profile (e.g., "PVCollada-2.0-PVsyst") in parallel with the standard technique, using a unique namespace. ```xml 15.3 10.1 150 Helios 3D PVsyst ``` -------------------------------- ### Schema file location Source: https://pvlib.github.io/pvcollada/dev_guide.html Specifies the location of the PVCollada 2.0 schema file within the repository. This schema imports the COLLADA schema and defines PV-specific enumerations and types. ```text schema/pvcollada_schema_2.0.xsd ``` -------------------------------- ### Validate PVCollada XML with lxml Source: https://pvlib.github.io/pvcollada/dev_guide.html Validates a PVCollada XML file against the schema using lxml. Prints a success message or lists validation errors from the schema error log. ```python from lxml import etree XML_FILE_PATH = "../Examples/05 - VerySimpleFixedPVC2_with_electrical_layout.pvc2" XSD_FILE_PATH = "pvcollada_schema_2.0.xsd" with open(XML_FILE_PATH, "rb") as xml: xml_doc = etree.XML(xml.read()) with open(XSD_FILE_PATH, "rb") as xsd: schema_root = etree.XML(xsd.read()) schema = etree.XMLSchema(schema_root) if schema.validate(xml_doc): print("XML is valid.") else: print("! XML is invalid.") for error in schema.error_log: print(" -", error.message) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.