--- title: Vi har længe haft en drøm for Orø subtitle: Vi har længe haft en drøm for Orø date: 2024-04-22 author: - name: Dorte Sørensen categories: [natur, bæredygtighed, landbrug, økologi] draft: true --- ::: {.lead} En drøm om en mark uden sprøjtning og med varierede afgrøder. Med plads til frugttræer og buske og mulighed for at dyrke økologiske grøntsager. Og med en fælled med legeområder, kunstoplevelser og små søer til tudserne. ::: Vi er ved at realisere det på Nørrestængevej overfor genbrugspladsen. Men det vil tage nogle år. Foreløbig har vi fået støtte fra Danmarks Økologiske Jordbrugsfond, der har købt marken, som vi nu forpagter. ![Der arbejdes og blomsterne nydes. Foto: Marianne Klug-Andersen](kvinder.jpg) ## Skovlandbrug Her har vi plantet ca. 700 træer med spisekastanjer og valnødder. De er plantet i smukke rækker ned langs bakkerne, så de udnytter vand og næring bedst muligt. Men de er små, så de kan endnu knap skimtes mellem alt det ukrudt, der kommer, når vi ikke sprøjter. Vi har sået kvælstofsamlende planter i bælter mellem trærækkerne, men det varer lidt, før det rigtig kan ses. Her i vinter har al ukrudtet faktisk skabt læ for træerne, men inden længe bliver der slået. Træerne skaffer os, når de dyrkes økologisk, et frugt- og bærtilskud fra Landbrugsministeriet, så vi har råd til forpagtningsafgiften. Og om 10-12 år kan vi nok høste de første nødder og kastanjer. Der er meget arbejde i at passe træerne. Vi har måttet indhegne området, så de ikke blev spist af harer og rådyr, og vi har måttet vande i tørre perioder. Selv om der er indhegnet, er alle velkomne til at færdes på stier i området, hvis man husker at lukke lågerne og holde hundene i snor, så træerne får fred til at vokse. Fælleden er også ved at tage form. Der er plantet læhegn, æbletræer og frugtbuske. Og vi arbejder ihærdigt på at skaffe midler til etablering af en lille sø. Det har kostet en del at købe de mange træer, som skulle være økologisk certificerede. Vi har med hjælp fra Coops Crowdfunding fået noget, og vi har fået private donationer. Mens træerne vokser til, er der masser af jord, der kan dyrkes. Man kan få en jordbrugsret i et eller flere år mod en mindre årlig afgift. Så mange er allerede i gang med grøntsager til eget brug og forhåbentlig til salg i en bod på området. ![Der flishugges store mængder. Foto: Marianne Klug-Andersen](traktor.jpg) ## Frivilligt arbejde Arbejdet med jorden er vi en gruppe frivillige, der står for. Planlægningen af aktiviteter foregår i et valgt fællesråd med månedlige møder, som man er velkommen til at deltage i. Lige nu er arbejdet organiseret i en række arbejdsdage, som ofte lægges i forbindelse med ferieperioder. Desuden er der en mindre gruppe, som mødes en gang om ugen for at slå græs, plante flere træer og passe de træer, der allerede er der. Vi vil meget gerne have flere hænder. Så hvis du deler drømmen om en økologisk nøddeplantage med plads til en mangfoldighed af dyr, mennesker og afgrøder, er du meget velkommen. Arbejdsdage og indholdet på dagene annonceres på Orø Fællesjords facebookside. Den faste gruppe mødes oftest tirsdage om formiddagen fra kl. 10, SMS til Anna: 2575 3699, Desuden afholdes fællesmøde 2. søndag i måneden kl. 10 - 11.30 med efterfølgende arbejdsdag. Vi mødes i drivhuset på Hestebedgaard, og alle er velkomne. ![Arbejdsdag på Orø Fællesjord. Foto: Anna Agger](kvinde.jpg) ::: {.callout-note} Facebookside: Meld dig ind ved at skrive til Kontingentet er 250 kr. pr. år, og betales til **MobilePay nr. 4573PV**, eller via Merkur bank: **Reg.nr. 8401 kontonr. 1146374**. Som medlem får du vores nyhedsbrev med opdateringer om aktiviteter i foreningen og på jorden. Hjemmeside: ::: positeModes(Enum):
  • fullscreen = 0
  • side_by_side_equal = 1
  • side_by_side_preview = 2
  • picture_in_picture = 3
  • class PadState(object):
  • def __init__(self):
  • self.reset()
  • def reset(self):
  • self.alpha = 1.0
  • self.xpos = 0
  • self.ypos = 0
  • self.zorder = 1
  • self.width = 0
  • self.height = 0
  • class VideoMix(object):
  • log = logging.getLogger('VideoMix')
  • def __init__(self):
  • self.caps = Config.get('mix', 'videocaps')
  • self.names = Config.getlist('mix', 'sources')
  • self.log.info('Configuring Mixer for %u Sources', len(self.names))
  • pipeline = """
  • compositor name=mix !
  • {caps} !
  • identity name=sig !
  • queue !
  • tee name=tee
  • intervideosrc channel=video_background !
  • {caps} !
  • mix.
  • tee. ! queue ! intervideosink channel=video_mix_out
  • """.format(
  • caps=self.caps
  • )
  • if Config.getboolean('previews', 'enabled'):
  • pipeline += """
  • tee. ! queue ! intervideosink channel=video_mix_preview
  • """
  • if Config.getboolean('stream-blanker', 'enabled'):
  • pipeline += """
  • tee. ! queue ! intervideosink channel=video_mix_streamblanker
  • """
  • for idx, name in enumerate(self.names):
  • pipeline += """
  • intervideosrc channel=video_{name}_mixer !
  • mix.
  • """.format(
  • name=name,
  • caps=self.caps,
  • idx=idx
  • )
  • self.log.debug('Creating Mixing-Pipeline:\n%s', pipeline)
  • self.mixingPipeline = Gst.parse_launch(pipeline)
  • self.log.debug('Binding Error & End-of-Stream-Signal on Mixing-Pipeline')
  • self.mixingPipeline.bus.add_signal_watch()
  • self.mixingPipeline.bus.connect("message::eos", self.on_eos)
  • self.mixingPipeline.bus.connect("message::error", self.on_error)
  • self.log.debug('Binding Handoff-Handler for Synchronus mixer manipulation')
  • sig = self.mixingPipeline.get_by_name('sig')
  • sig.connect('handoff', self.on_handoff)
  • self.padStateDirty = False
  • self.padState = list()
  • for idx, name in enumerate(self.names):
  • self.padState.append(PadState())
  • self.log.debug('Initializing Mixer-State')
  • self.compositeMode = CompositeModes.fullscreen
  • self.sourceA = 0
  • self.sourceB = 1
  • self.recalculateMixerState()
  • self.applyMixerState()
  • bgMixerpad = self.mixingPipeline.get_by_name('mix').get_static_pad('sink_0')
  • bgMixerpad.set_property('zorder', 0)
  • self.log.debug('Launching Mixing-Pipeline')
  • self.mixingPipeline.set_state(Gst.State.PLAYING)
  • def getInputVideoSize(self):
  • caps = Gst.Caps.from_string(self.caps)
  • struct = caps.get_structure(0)
  • _, width = struct.get_int('width')
  • _, height = struct.get_int('height')
  • return width, height
  • def recalculateMixerState(self):
  • if self.compositeMode == CompositeModes.fullscreen:
  • self.recalculateMixerStateFullscreen()
  • elif self.compositeMode == CompositeModes.side_by_side_equal:
  • self.recalculateMixerStateSideBySideEqual()
  • elif self.compositeMode == CompositeModes.side_by_side_preview:
  • self.recalculateMixerStateSideBySidePreview()
  • elif self.compositeMode == CompositeModes.picture_in_picture:
  • self.recalculateMixerStatePictureInPicture()
  • self.log.debug('Marking Pad-State as Dirty')
  • self.padStateDirty = True
  • def recalculateMixerStateFullscreen(self):
  • self.log.info('Updating Mixer-State for Fullscreen-Composition')
  • for idx, name in enumerate(self.names):
  • pad = self.padState[idx]
  • pad.reset()
  • pad.alpha = float(idx == self.sourceA)
  • def recalculateMixerStateSideBySideEqual(self):
  • self.log.info('Updating Mixer-State for Side-by-side-Equal-Composition')
  • width, height = self.getInputVideoSize()
  • self.log.debug('Video-Size parsed as %ux%u', width, height)
  • try:
  • gutter = Config.getint('side-by-side-equal', 'gutter')
  • self.log.debug('Gutter configured to %u', gutter)
  • except:
  • gutter = int(width / 100)
  • self.log.debug('Gutter calculated to %u', gutter)
  • targetWidth = int((width - gutter) / 2)
  • targetHeight = int(targetWidth / width * height)
  • try:
  • y = Config.getint('side-by-side-equal', 'ypos')
  • self.log.debug('Y-Pos configured to %u', y)
  • except:
  • y = (height - targetHeight) / 2
  • self.log.debug('Y-Pos calculated to %u', y)
  • xa = 0
  • xb = width - targetWidth
  • for idx, name in enumerate(self.names):
  • pad = self.padState[idx]
  • pad.reset()
  • pad.ypos = y
  • pad.width = targetWidth
  • pad.height = targetHeight
  • if idx == self.sourceA:
  • pad.xpos = xa
  • pad.zorder = 1
  • elif idx == self.sourceB:
  • pad.xpos = xb
  • pad.zorder = 2
  • else:
  • pad.alpha = 0
  • def recalculateMixerStateSideBySidePreview(self):
  • self.log.info('Updating Mixer-State for Side-by-side-Preview-Composition')
  • width, height = self.getInputVideoSize()
  • self.log.debug('Video-Size parsed as %ux%u', width, height)
  • try:
  • asize = [int(i) for i in Config.get('side-by-side-preview', 'asize').split('x', 1)]
  • self.log.debug('A-Video-Size configured to %ux%u', asize[0], asize[1])
  • except:
  • asize = [
  • int(width / 1.25), # 80%
  • int(height / 1.25) # 80%
  • ]
  • self.log.debug('A-Video-Size calculated to %ux%u', asize[0], asize[1])
  • try:
  • apos = [int(i) for i in Config.get('side-by-side-preview', 'apos').split('/', 1)]
  • self.log.debug('B-Video-Position configured to %u/%u', apos[0], apos[1])
  • except:
  • apos = [
  • int(width / 100), # 1%
  • int(width / 100) # 1%
  • ]
  • self.log.debug('B-Video-Position calculated to %u/%u', apos[0], apos[1])
  • try:
  • bsize = [int(i) for i in Config.get('side-by-side-preview', 'bsize').split('x', 1)]
  • self.log.debug('B-Video-Size configured to %ux%u', bsize[0], bsize[1])
  • except:
  • bsize = [
  • int(width / 4), # 25%
  • int(height / 4) # 25%
  • ]
  • self.log.debug('B-Video-Size calculated to %ux%u', bsize[0], bsize[1])
  • try:
  • bpos = [int(i) for i in Config.get('side-by-side-preview', 'bpos').split('/', 1)]
  • self.log.debug('B-Video-Position configured to %u/%u', bpos[0], bpos[1])
  • except:
  • bpos = [
  • width - int(width / 100) - bsize[0],
  • height - int(width / 100) - bsize[1] # 1%
  • ]
  • self.log.debug('B-Video-Position calculated to %u/%u', bpos[0], bpos[1])
  • for idx, name in enumerate(self.names):
  • pad = self.padState[idx]
  • pad.reset()
  • if idx == self.sourceA:
  • pad.xpos, pad.ypos = apos
  • pad.width, pad.height = asize
  • pad.zorder = 1
  • elif idx == self.sourceB:
  • pad.xpos, pad.ypos = bpos
  • pad.width, pad.height = bsize
  • pad.zorder = 2
  • else:
  • pad.alpha = 0
  • def recalculateMixerStatePictureInPicture(self):
  • self.log.info('Updating Mixer-State for Picture-in-Picture-Composition')
  • width, height = self.getInputVideoSize()
  • self.log.debug('Video-Size parsed as %ux%u', width, height)
  • try:
  • pipsize = [int(i) for i in Config.get('picture-in-picture', 'pipsize').split('x', 1)]
  • self.log.debug('PIP-Size configured to %ux%u', pipsize[0], pipsize[1])
  • except:
  • pipsize = [
  • int(width / 4), # 25%
  • int(height / 4) # 25%
  • ]
  • self.log.debug('PIP-Size calculated to %ux%u', pipsize[0], pipsize[1])
  • try:
  • pippos = [int(i) for i in Config.get('picture-in-picture', 'pippos').split('/', 1)]
  • self.log.debug('PIP-Position configured to %u/%u', pippos[0], pippos[1])
  • except:
  • pippos = [
  • width - pipsize[0] - int(width / 100), # 1%
  • height - pipsize[1] -int(width / 100) # 1%
  • ]
  • self.log.debug('PIP-Position calculated to %u/%u', pippos[0], pippos[1])
  • for idx, name in enumerate(self.names):
  • pad = self.padState[idx]
  • pad.reset()
  • if idx == self.sourceA:
  • pass
  • elif idx == self.sourceB:
  • pad.xpos, pad.ypos = pippos
  • pad.width, pad.height = pipsize
  • pad.zorder = 2
  • else:
  • pad.alpha = 0
  • def applyMixerState(self):
  • for idx, state in enumerate(self.padState):
  • # mixerpad 0 = background
  • mixerpad = self.mixingPipeline.get_by_name('mix').get_static_pad('sink_%u' % (idx+1))
  • self.log.debug('Reconfiguring Mixerpad %u to x/y=%u/%u, w/h=%u/%u alpha=%0.2f, zorder=%u', \
  • idx, state.xpos, state.ypos, state.width, state.height, state.alpha, state.zorder)
  • mixerpad.set_property('xpos', state.xpos)
  • mixerpad.set_property('ypos', state.ypos)
  • mixerpad.set_property('width', state.width)
  • mixerpad.set_property('height', state.height)
  • mixerpad.set_property('alpha', state.alpha)
  • mixerpad.set_property('zorder', state.zorder)
  • def on_handoff(self, object, buffer):
  • if self.padStateDirty:
  • self.padStateDirty = False
  • self.log.debug('[Streaming-Thread]: Pad-State is Dirty, applying new Mixer-State')
  • self.applyMixerState()
  • def on_eos(self, bus, message):
  • self.log.debug('Received End-of-Stream-Signal on Mixing-Pipeline')
  • def on_error(self, bus, message):
  • self.log.debug('Received Error-Signal on Mixing-Pipeline')
  • (error, debug) = message.parse_error()
  • self.log.debug('Error-Details: #%u: %s', error.code, debug)
  • def setVideoSourceA(self, source):
  • # swap if required
  • if self.sourceB == source:
  • self.sourceB = self.sourceA
  • self.sourceA = source
  • self.recalculateMixerState()
  • def getVideoSourceA(self):
  • return self.sourceA
  • def setVideoSourceB(self, source):
  • # swap if required
  • if self.sourceA == source:
  • self.sourceA = self.sourceB
  • self.sourceB = source
  • self.recalculateMixerState()
  • def getVideoSourceB(self):
  • return self.sourceB
  • def setCompositeMode(self, mode):
  • self.compositeMode = mode
  • self.recalculateMixerState()
  • def getCompositeMode(self):
  • return self.compositeMode