Получение видимого реагирует содержания UIScrollView

Основные шаги для получения решений:

  1. считывают 2 файла данных в кадры данных
  2. устанавливают CRS ('epsg: 4326') и создают геометрию точки из (lat, long) для обоих фреймов данных
  3. для фрейма данных schools преобразуйте CRS в UTMzone 33N
  4. выполните буферизацию (радиус = 500 м) на schools фрейме данных
  5. на schools фрейм данных, выполните и установите 500-метровый буфер, поскольку новые geometry
  6. выполняют правильное пространственное соединение между houses и schools в общем CRS
  7. получают результат в houses_joined фрейме данных [1116 ]

Вот рабочий код:

import pandas as pd
import geopandas as gpd
from shapely.geometry import Point, Polygon

# School data
# -----------
# read `schools.csv`, data are in (lat,long); 'epsg:4326'
#
# lat;lon;school_name
# 56.039484;14.164114;Parkskolan
# 56.029687;14.159337;Centralskolan
df_schools = pd.read_csv('schools.csv', na_values=['NaN'], sep=';')

# create Point geometry objects from (lon,lat)
sch_geom = [Point(xy) for xy in zip(df_schools.lon, df_schools.lat)]
# set initial coordinate ref system, and geometry column to the dataframe
gdf_schools = gpd.GeoDataFrame(df_schools, crs={'init': 'epsg:4326'}, geometry=sch_geom)

# convert CRS from (lat,long) to UTMzone 33N
# and get new dataframe: gdf_schools_utm33N
gdf_schools_utm33N = gdf_schools.to_crs(crs="+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
# Note: crs="..." can be replaced by epsg=32633

# do buffering, radius: 500m
gdf_schools_utm33N['buffer_geometry'] = gdf_schools_utm33N.geometry.buffer(500)

# rename `geometry` -> `original_geometry`; `buffer_geometry` -> geometry
# .. and set column `geometry` as the default geometry data of the geodataframe.
gdf_schools_utm33N = gdf_schools_utm33N.rename(
    columns={'geometry':'original_geometry', 'buffer_geometry':'geometry'}).set_geometry('geometry')

# Houses data
# -----------
# read `houses.csv`, data are in (lat,long); 'epsg:4326'

# lat;lon;houseid
# 56.039240;14.165066;1
# 56.039008;14.166709;2
# 56.038608;14.169420;3
# 56.046108;14.171420;4

df_houses = pd.read_csv('houses.csv', na_values=['NaN'], sep=';')
# I add the 4th house that is too far away from all schools
# The 4th house: 56.046108  14.171420   4

# create Point geometry for the houses, and init CRS
hs_geom = [Point(xy) for xy in zip(df_houses.lon, df_houses.lat)]
gdf_houses = gpd.GeoDataFrame(df_houses, crs={'init': 'epsg:4326'}, geometry=hs_geom)

# options: plot the schools' buffers and all the houses
ax = gdf_schools_utm33N.plot(color='lightgray', edgecolor='green', alpha=0.5)
gdf_houses.to_crs(epsg=32633).plot(ax=ax, color='red')

# ******* Spatial Join *****************
# houses data frame needs CRS conversion
hss = gdf_houses.to_crs(epsg=32633)
# do spatial join of houses(points) ~ schools(circles of 500m radius)
houses_joined = gpd.sjoin(hss, gdf_schools_utm33N, op='within', how='inner')
# print out the successful joined rows (house_id, school_names)

# this prints house_id + school_name 
houses_joined[['houseid','school_name']]

# Output: house_id, school_name
# 1    Parkskolan
# 2    Parkskolan
# 3    Parkskolan

Полученный сюжет:

enter image description here

69
задан Ajumal 27 April 2015 в 10:33
поделиться

3 ответа

Отвечая на свой вопрос, в основном благодаря ответу Джима Дови, который не совсем помог, но дал мне основу для моего ответа:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.bounds.size;

float theScale = 1.0 / scale;
visibleRect.origin.x *= theScale;
visibleRect.origin.y *= theScale;
visibleRect.size.width *= theScale;
visibleRect.size.height *= theScale;

Основное отличие состоит в том, что размер для visibleRect должно быть scrollView.bounds.size , а не scrollView.contentSize , который является размером представления содержимого. Также немного упростили математику и не совсем увидели использование isless () , которая нарушала бы код, когда он больше.

83
ответ дан 24 November 2019 в 13:35
поделиться

Вы должны вычислить ее, используя свойства contentOffset и contentSize UIScrollView, например:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.contentSize;

Затем вы можете зарегистрировать это для проверки работоспособности:

NSLog( @"Visible rect: %@", NSStringFromCGRect(visibleRect) );

Чтобы учесть масштабирование (если это еще не сделано с помощью свойства contentSize), вам нужно будет разделить каждую координату на zoomScale, или для лучшей производительности умножьте на 1.0 / zoomScale:

CGFloat scale = (CGFloat) 1.0 / scrollView.zoomScale;
if ( isless(scale, 1.0) )      // you need to #include <math.h> for isless()
{
    visibleRect.origin.x *= scale;
    visibleRect.origin.y *= scale;
    visibleRect.size.width *= scale;
    visibleRect.size.height *= scale;
}

Кроме того: я использую isless (), isgreater (), isequal () и т. Д. Из math.h, потому что они (предположительно) будут делать правильные вещи в отношении «неупорядоченных» результатов сравнения с плавающей запятой и других странных и замечательных, специфичных для архитектуры. Случаи FP.


Изменить: вам нужно использовать bounds.size вместо contentSize при вычислении visibleRect.size .

.
28
ответ дан 24 November 2019 в 13:35
поделиться

I don't think that a UIScrollView gives you that rectangle directly, but I think you have all the necessary items to calculate it.

A combination of the bounds, the contentOffset and the zoomScale should be all you need to create the rectangle you are looking for.

0
ответ дан 24 November 2019 в 13:35
поделиться